home *** CD-ROM | disk | FTP | other *** search
/ Usenet 1993 July / InfoMagic USENET CD-ROM July 1993.ISO / sources / misc / volume9 / pc-mail-nfs < prev    next >
Encoding:
Text File  |  1989-11-26  |  64.7 KB  |  2,511 lines

  1. Newsgroups: comp.sources.misc
  2. organization: Eindhoven University of Technology, The Netherlands
  3. keywords: pc-mail-nfs
  4. subject: v09i006: pc-mail over nfs
  5. from: allbery@uunet.UU.NET (Brandon S. Allbery - comp.sources.misc)
  6. Reply-To: wietse@wzv.win.tue.nl (Wietse Z. Venema)
  7.  
  8. Posting-number: Volume 9, Issue 6
  9. Submitted-by: wietse@wzv.win.tue.nl (Wietse Z. Venema)
  10. Archive-name: pc-mail-nfs
  11.  
  12. This is an extension to the pc-mail package (uucp mail for pc's) that
  13. appeared in comp.sources.misc, april 1988.  It is intended for an
  14. environment where pc-mail users mount their personal mail directories
  15. from a file server.  The programs in the present package run on the file
  16. server.  They directly access the per-user pc-mail directories and thus
  17. replace the UUCP file transfer functions of the pc-mail software.  The
  18. programs were tested with SunOS 4.0.3 and Microport System-V/AT 2.3.
  19. This software is in the public domain.
  20.  
  21.     Wietse Venema (wswietse@lso.win.tue.nl)
  22.  
  23. #! /bin/sh
  24. # This is a shell archive.  Remove anything before this line, then unpack
  25. # it by saving it into a file and typing "sh file".  To overwrite existing
  26. # files, type "sh file -c".  You can also feed this as standard input via
  27. # unshar, or by typing "sh <file", e.g..  If this archive is complete, you
  28. # will see the following message at the end:
  29. #        "End of shell archive."
  30. # Contents:  README pc-mail.c pc-maild.c Makefile sysexits.h syslog.h
  31. #   syslog.c util.c util.h mtime.c mtime.h dosunix.c dosunix.h
  32. #   percentm.h percentm.c pc-mail.8 pc-maild.8
  33. # Wrapped by wietse@wzv on Sun Nov 19 14:01:07 1989
  34. PATH=/bin:/usr/bin:/usr/ucb ; export PATH
  35. if test -f 'README' -a "${1}" != "-c" ; then 
  36.   echo shar: Will not clobber existing file \"'README'\"
  37. else
  38. echo shar: Extracting \"'README'\" \(6589 characters\)
  39. sed "s/^X//" >'README' <<'END_OF_FILE'
  40. X@(#) README 1.6 11/19/89 14:00:51
  41. X
  42. XThis is an extension to the pc-mail package (uucp mail for pc's) that
  43. Xappeared in comp.sources.misc, april 1988.  It is intended for an
  44. Xenvironment where pc-mail users mount their personal mail directories
  45. Xfrom a file server.  The programs in the present package run on the file
  46. Xserver.  They directly access the per-user pc-mail directories and thus
  47. Xreplace the UUCP file transfer functions of the pc-mail software.  The
  48. Xprograms were tested with SunOS 4.0.3 and Microport System-V/AT 2.3.
  49. XThis software is in the public domain.
  50. X
  51. XPlease report any problems etc.  to the author (Wietse Venema) via one
  52. Xof the following e-mail addresses:
  53. X
  54. X    wswietse@lso.win.tue.nl
  55. X    wswietse@heitue5.bitnet
  56. X
  57. XThe remainder of this document describes the operation of the software,
  58. Xhow to install the software, how to add new users, and how to migrate
  59. Xusers from pc-mail over UUCP to pc-mail over PC-NFS.
  60. X
  61. XOperation
  62. X=========
  63. X
  64. XThe UUCP file transfer functions of the pc-mail "cico.exe" program are
  65. Xtaken over by the following two programs that run on the file server:
  66. X
  67. Xpc-mail:    deliver mail to a user's mail directory (the receiving
  68. X        function of the "cico.exe" program). This program is 
  69. X        intended to be called by sendmail.
  70. X
  71. Xpc-maild:    scan user mail directories for unsent mail, and pipe it 
  72. X        through the UNIX rmail command (the sending function of 
  73. X        the "cico.exe" program).
  74. X
  75. XInstallation on the server
  76. X==========================
  77. X
  78. XBuild the pc-mail and pc-maild programs. In the Makefile, you can
  79. Xdefine the location of the executable programs and the pc-mail spool
  80. Xarea, and how often the daemon program will scan user directories for
  81. Xunsent mail. You will probably have to do `make depend' before you
  82. Xcan compile the programs.
  83. X
  84. XExecute the following command to create a pc-mail spool area, and
  85. Xinstall the pc-mail and pc-maild programs.  You must be root.
  86. X
  87. X    % make install
  88. X
  89. XThe output from the "make" command will depend on how you specified the
  90. Xpath names in the Makefile:
  91. X
  92. X    mkdir /var/spool/pc-mail
  93. X    chmod 755 /var/spool/pc-mail
  94. X    cp pc-mail pc-maild /usr/local/lib
  95. X    chown root /usr/local/lib/pc-mail
  96. X    chmod u+s /usr/local/lib/pc-mail
  97. X
  98. XExecute the following command to install the manual pages, if you want
  99. Xto. 
  100. X
  101. X    % make installman
  102. X
  103. XAgain, output from make will depend on what you specified in the
  104. XMakefile:
  105. X
  106. X    cp pc-mail.8 pc-maild.8 /usr/local/man/man8
  107. X
  108. XAdd a line with the command
  109. X
  110. X    /usr/local/lib/pc-maild
  111. X
  112. Xto the file /etc/rc.local (the exact name of the rc script depends on
  113. Xyour version of unix, and the exact path name of the pc-maild program
  114. Xdepends on where you installed it).
  115. X
  116. XFor now, you will have to start the pc-maild program by hand (unless
  117. Xyou wish to reboot the machine).
  118. X
  119. XAdd to the sendmail.cf file a line that looks like:
  120. X
  121. X    Mpc,    P=/usr/local/lib/pc-mail, F=lsDFMn, S=xxx, R=yyy, A=pc-mail $u
  122. X
  123. XWhere xxx and yyy may be the same rewriting rules as used for the local
  124. Xmailer (usually defined with the "Mlocal" line).
  125. X
  126. XIn sendmail.cf, at the end of ruleset S0, just before the local mailer
  127. Xwill be invoked (something like "R$*    $#local $:$1"), add a line with
  128. X
  129. X    R $=X            $#pc $:$1
  130. X
  131. XUse a different letter if X is already in use.  A later section
  132. Xdescribes how to convince sendmail that X is a list of login names of
  133. Xpc-mail users.
  134. X
  135. XAdding users (server side)
  136. X==========================
  137. X
  138. XAdd the user to the password data base.  In the spool area on the
  139. Xserver, create a subdirectory for the pc-mail user.  The directory must
  140. Xbe owned by that user; for reasons of privacy, mode 0700 is recommended.
  141. XIn the following example, replace username by the actual login name of
  142. Xthe user.
  143. X
  144. X    % mkdir /var/spool/pc-mail/username
  145. X    % chown username /var/spool/pc-mail/username
  146. X    % chmod 700 /var/spool/pc-mail/username
  147. X
  148. XAdding users (pc side)
  149. X======================
  150. X
  151. XOn the pc, adjust the AUTOEXEC.BAT, NETWORK.BAT or DRIVES.BAT files so
  152. Xthat they contain the following commands (replacing server by the name
  153. Xof the NFS server host, and replacing username by the login name of the
  154. Xactual user):
  155. X
  156. X    net name username *
  157. X    net use m: \\server\var\spool\pc-mail\username
  158. X    set MAILDIR=m:\
  159. X
  160. XThe trailing \ is needed on the last command, or the mail program will
  161. Xcomplain that it "cannot access some essential data files".
  162. X
  163. XIf the user had a UUCP-based pc-mail link, you can now remove the -p
  164. Xoption from any CMAIL commands that may appear in batch files.
  165. X
  166. XReboot the pc.
  167. X
  168. XIf the user had a UUCP-based pc-mail link, copy the contents of the
  169. Xuser's LOCAL mail directory to the REMOTE mail directory on the file
  170. Xserver.  From now on the local mail directory will no longer be needed.
  171. X
  172. XTest if the mail program works by creating a small mail message. Since
  173. Xthe message will automatically be picked up by the pc-maild program the
  174. Xfiles may disappear before you had a chance to type a DIR command!
  175. X
  176. XAdding users (server side again)
  177. X================================
  178. X
  179. XAdd the user to the list of NFS pc-mail users.  There are two ways to
  180. Xaccomplish the same result. The list of users can be hardcoded in the
  181. Xsendmail.cf file, e.g.:
  182. X
  183. X    CXjohn marsha
  184. X
  185. XMultiple usernames on a line, and multiple CX lines are allowed.  A
  186. Xbetter way is to have sendmail read the list from an external file,
  187. Xby putting the following line into the sendmail.cf file:
  188. X
  189. X    FX/etc/pc-mail-users %s
  190. X
  191. XThe /etc/pc-mail-users file should contain only a single login name per
  192. Xline.
  193. X
  194. XKill the sendmail daemon and restart it.
  195. X
  196. XIf the user had a UUCP-based pc-mail connection, you can now get rid of
  197. Xaliases that were needed for UUCP support.
  198. X
  199. XNote that the sendmail ON THE NFS SERVER will not read the user's
  200. X.forward file.  The file will still be useful, however, if the user's
  201. Xhome directory is exported to OTHER hosts running sendmail.  In that
  202. Xcase you will want to create a .forward file in the user's home
  203. Xdirectory containing
  204. X
  205. X    username@fully-qualified-hostname
  206. X
  207. XAdding users (pc side again)
  208. X============================
  209. X
  210. XThis step can be skipped if the user had no UUCP-based pc-mail connection.
  211. X
  212. XIf the user used to have a UUCP connection, pick up any mail that still
  213. Xresides in the UUCP spool area on the file server (the mail will now be
  214. Xstored in the user's private remote mail directory through the miracles
  215. Xof NFS). 
  216. X
  217. XAt this point the cico.exe program has become obsolete. You may consider
  218. Xto replace it by a small C program that does nothing.
  219. X
  220. XAdding users (server side again)
  221. X================================
  222. X
  223. XThis step can be skipped if the user had no UUCP-based pc-mail connection.
  224. X
  225. XThe user's uucp login can be removed from the password file.
  226. END_OF_FILE
  227. if test 6589 -ne `wc -c <'README'`; then
  228.     echo shar: \"'README'\" unpacked with wrong size!
  229. fi
  230. # end of 'README'
  231. fi
  232. if test -f 'pc-mail.c' -a "${1}" != "-c" ; then 
  233.   echo shar: Will not clobber existing file \"'pc-mail.c'\"
  234. else
  235. echo shar: Extracting \"'pc-mail.c'\" \(10884 characters\)
  236. sed "s/^X//" >'pc-mail.c' <<'END_OF_FILE'
  237. X/*++
  238. X/* NAME
  239. X/*    pc-mail 8
  240. X/* SUMMARY
  241. X/*    deliver mail to nfs-based pc-mail users
  242. X/* PROJECT
  243. X/*    pc-mail
  244. X/* PACKAGE
  245. X/*    nfs
  246. X/* SYNOPSIS
  247. X/*    pc-mail user
  248. X/* DESCRIPTION
  249. X/*    This program is to be run on the nfs server that exports mail
  250. X/*    directories to MS-DOS pc-mail users. The program replaces the
  251. X/*    UNIX -> MS-DOS file transfer function of the MS-DOS \fIcico\fR
  252. X/*    program.
  253. X/*
  254. X/*    Normally, the pc-mail delivery program is invoked by sendmail(8).
  255. X/*    Its purpose is to deliver new mail in the mail directory of the
  256. X/*    specified \fIuser\fR (default /var/spool/pc-mail/\fIuser\fR).
  257. X/*    Any error conditions detected by the pc-mail delivery program
  258. X/*    are reported back in a sendmail-compatible manner.
  259. X/*
  260. X/*    This program must be run with root privileges. It will assume
  261. X/*    the (uid, gid) of the specified user before delivering mail.
  262. X/*
  263. X/*    The program attempts to create any missing directories, and to
  264. X/*    correct ownerships or protections where needed.
  265. X/* FILES
  266. X/*    /usr/spool/pc-mail/\fIuser\fR/nNNNNN, mail message.
  267. X/*    /usr/spool/pc-mail/\fIuser\fR/hNNNNN, sender of message.
  268. X/*    (NNNNN is the pc-mail "message id").
  269. X/* SEE ALSO
  270. X/*    pc-maild(1)
  271. X/* DIAGNOSTICS
  272. X/*    All conceivable error conditions cause the program to terminate
  273. X/*    with a non-zero exit status, after printing an error message on
  274. X/*    the standard error stream, and appending an entry to the system log.
  275. X/*    See <sysexits.h> for details.
  276. X/* BUGS
  277. X/*    There is no way to notify a pc-mail user of the arrival of new mail.
  278. X/* AUTHOR(S)
  279. X/*    W.Z. Venema
  280. X/*    Eindhoven University of Technology
  281. X/*    Department of Mathematics and Computer Science
  282. X/*    Den Dolech 2, P.O. Box 513, 5600 MB Eindhoven, The Netherlands
  283. X/* CREATION DATE
  284. X/*    Sun Oct 22 18:00:53 MED 1989
  285. X/* LAST MODIFICATION
  286. X/*    11/19/89 13:46:04
  287. X/* VERSION/RELEASE
  288. X/*    1.2
  289. X/*--*/
  290. X
  291. X#ifndef lint
  292. Xstatic char sccsid[] = "@(#) pc-mail.c 1.2 11/19/89 13:46:04";
  293. X
  294. X#endif
  295. X
  296. X#include <stdio.h>
  297. X#include <sys/types.h>
  298. X#include <sys/stat.h>
  299. X#include <pwd.h>
  300. X#include <varargs.h>
  301. X
  302. X#ifdef SYSLOG
  303. X#include <syslog.h>
  304. X#else
  305. X#include "syslog.h"
  306. X#endif
  307. X
  308. X#ifdef SYSV
  309. X#include <ndir.h>
  310. X#else
  311. X#include <sys/dir.h>
  312. X#endif
  313. X
  314. X#ifdef    SYSEXITS
  315. X#include <sysexits.h>
  316. X#else
  317. X#include "sysexits.h"
  318. X#endif
  319. X
  320. X#include "dosunix.h"
  321. X#include "percentm.h"
  322. X
  323. X/* Stuff related to failed system calls */
  324. X
  325. Xextern int errno;
  326. X
  327. X/* External functions */
  328. X
  329. Xextern struct passwd *getpwnam();
  330. Xextern long time();
  331. Xextern char *mktemp();
  332. Xextern void exit();
  333. Xextern unsigned sleep();
  334. X
  335. X/* Local declarations */
  336. X
  337. X#ifndef    MAILDIR
  338. X#define    MAILDIR    "/usr/spool/pc-mail"    /* pc-mail directory tree */
  339. X#endif
  340. X
  341. X#define    LOCK    "pc-mail.lck"        /* the lock file */
  342. X#define    STALE    1800            /* max age of lock file */
  343. X#define    MAXTRY    60            /* max retry count for lock creation */
  344. X#define    MSGFIL_FMT    "n%05d"        /* message file name format */
  345. X#define    SNDFIL_FMT    "h%05d"        /* sender file name format */
  346. X
  347. Xchar    template[] = "pc.XXXXXX";    /* template lock file */
  348. X
  349. X/* local functions */
  350. X
  351. Xvoid    sender();
  352. Xvoid    message();
  353. Xvoid    error();
  354. X
  355. Xchar   *progname;
  356. X
  357. Xmain(argc, argv)
  358. Xint     argc;
  359. Xchar  **argv;
  360. X{
  361. X    struct passwd *pwd;
  362. X    static char userdir[BUFSIZ];
  363. X    int     seqno;
  364. X
  365. X    progname = argv[0];
  366. X
  367. X    /* Garbage in, garbage out */
  368. X
  369. X    if (argc != 2)
  370. X    error(EX_USAGE, "usage: %s user", *argv);
  371. X
  372. X#ifndef DEBUG
  373. X    if (geteuid() != 0)
  374. X    error(EX_USAGE, "must run with root privileges");
  375. X
  376. X    /* need this for SYSVR2 or mkdir(1) fails */
  377. X#ifdef SYSV
  378. X    if (setuid(0) != 0)
  379. X    error(EX_OSERR, "cannot setuid(0)");
  380. X#endif
  381. X#endif
  382. X
  383. X    if ((pwd = getpwnam(argv[1])) == 0)
  384. X    error(EX_NOUSER, "unknown user: %s", argv[1]);
  385. X
  386. X    /* Setup a somewhat safe environment */
  387. X
  388. X    if (putenv("PATH=/bin:/usr/bin:/usr/ucb")
  389. X    || putenv("IFS= \t\n"))
  390. X    error(EX_TEMPFAIL, "putenv() failed");
  391. X
  392. X    /* Check the necessary directories exist */
  393. X
  394. X    (void) sprintf(userdir, "%s/%s", MAILDIR, argv[1]);
  395. X    checkdir(userdir, pwd->pw_uid, pwd->pw_gid, 0700);
  396. X
  397. X    /* Now with that out of the way, try to deliver the message */
  398. X
  399. X    if (setgid(pwd->pw_gid))
  400. X    error(EX_USAGE, "setgid(%s) failed: %m", argv[1]);
  401. X    if (setuid(pwd->pw_uid))
  402. X    error(EX_USAGE, "setuid(%s) failed: %m", argv[1]);
  403. X
  404. X    /* make sure the user mail directory is accessible */
  405. X
  406. X    if (chdir(userdir))
  407. X    error(EX_TEMPFAIL, "can't access mail directory %s", userdir);
  408. X
  409. X    /* deliver mail */
  410. X
  411. X    seqno = newseqno(userdir);            /* Allocate sequence number */
  412. X    message(pwd, seqno);            /* Create message file */
  413. X    sender(seqno);                /* Create metafile (sender) */
  414. X    exit(EX_OK);                /* Done. */
  415. X    /* NOTREACHED */
  416. X}
  417. X
  418. X/* message - write message file */
  419. X
  420. Xvoid    message(pwd, seqno)
  421. Xstruct passwd *pwd;
  422. Xint     seqno;
  423. X{
  424. X    static char buf[BUFSIZ];
  425. X    register FILE *fp;
  426. X
  427. X    /* Create the message file */
  428. X
  429. X    (void) sprintf(buf, MSGFIL_FMT, seqno);
  430. X    if ((fp = fopen(buf, "w")) == 0)
  431. X    error(EX_CANTCREAT, "create error for file %s/%s: %m",
  432. X          pwd->pw_name, buf);
  433. X    if (unix2dos(stdin, fp)) {
  434. X    (void) unlink(buf);
  435. X    error(EX_CANTCREAT, "write error for file %s/%s: %m",
  436. X          pwd->pw_name, buf);
  437. X    }
  438. X    (void) fclose(fp);
  439. X    (void) chmod(buf, 0400);            /* Avoid tampering */
  440. X}
  441. X
  442. X/* sender - extract sender from message */
  443. X
  444. Xvoid    sender(seqno)
  445. Xint     seqno;
  446. X{
  447. X    register FILE *ifp;
  448. X    register FILE *ofp;
  449. X    static char fname[BUFSIZ];        /* file names */
  450. X    static char line[BUFSIZ];        /* read buffer */
  451. X    static char from[BUFSIZ] = "unknown";    /* sender */
  452. X
  453. X    /*
  454. X     * Try to open the message file; if that fails, let the pc software scan
  455. X     * for the sender at a later time.
  456. X     * 
  457. X     * We recognize the following From line formats:
  458. X     *
  459. X     * From name
  460. X     * 
  461. X     * >From name
  462. X     * 
  463. X     * From: address (full name)
  464. X     * 
  465. X     * From: full name <address>
  466. X     * 
  467. X     * From: full name
  468. X     */
  469. X
  470. X    (void) sprintf(fname, MSGFIL_FMT, seqno);
  471. X    if ((ifp = fopen(fname, "r")) == 0)
  472. X    return;
  473. X
  474. X    /* Extract sender from message */
  475. X
  476. X    while (dosgets(line, sizeof(line), ifp) && *line) {
  477. X    if (sscanf(line, "From: %*s ( %[^)] )", from) == 1)
  478. X        break;
  479. X    if (sscanf(line, "From: %[^<]", from) == 1)
  480. X        break;
  481. X    sscanf(line, "%*[>] From %s", from) || sscanf(line, "From %s", from);
  482. X    }
  483. X    (void) fclose(ifp);
  484. X
  485. X    /*
  486. X     * Try to create the meta file; if that fails, let the pc software try
  487. X     * again at a later time.
  488. X     */
  489. X
  490. X    (void) sprintf(fname, SNDFIL_FMT, seqno);
  491. X    if (ofp = fopen(fname, "w")) {
  492. X    (void) fprintf(ofp, "%s\r\n", from);
  493. X    if (fflush(ofp) || ferror(ofp) || feof(ofp) || fclose(ofp)) {
  494. X        (void) unlink(fname);
  495. X    } else {
  496. X        (void) chmod(fname, 0400);        /* avoid tampering */
  497. X    }
  498. X    }
  499. X}
  500. X
  501. X/* newseqno - allocate new message sequence number */
  502. X
  503. Xint     newseqno(userdir)
  504. Xchar   *userdir;
  505. X{
  506. X    register DIR *dd;
  507. X    register struct direct *p;
  508. X    struct stat st;
  509. X    register int seqno = 0;
  510. X    int     tmp = 0;
  511. X    int     i;
  512. X    char    junk;
  513. X
  514. X    /*
  515. X     * When the pc adds a file to the "mail data base", the file name is
  516. X     * composed of a single letter and a unique sequence number. The pc
  517. X     * chooses a new sequence number by adding one to the highest existing
  518. X     * sequence number.
  519. X     * 
  520. X     * Now that the pc mounts its mail directory from the nfs server we must
  521. X     * avoid possible concurrency conflicts when both pc and file server try
  522. X     * to update the "mail data base".
  523. X     * 
  524. X     * Since the pc does not know about concurrent access from the nfs server,
  525. X     * the server has to add 2 to the highest existing message sequence
  526. X     * number, in order to avoid conflicts. Fortunately, only one pc at a
  527. X     * time will be accessing a mail directory of a particular user.
  528. X     * 
  529. X     * Further concurrency conflicts are be avoided on the server side by using
  530. X     * lock files.
  531. X     * 
  532. X     * If we cannot create a lock file right now, we back off and let sendmail
  533. X     * try again later.
  534. X     */
  535. X
  536. X    /* Get rid of stale lock files */
  537. X
  538. X    if (stat(LOCK, &st) == 0 && st.st_mtime < time((long *) 0) - STALE)
  539. X    (void) unlink(LOCK);
  540. X
  541. X    /* Wait until we can create the lock file */
  542. X
  543. X    if (creat(mktemp(template), 0400) < 0)
  544. X    error(EX_TEMPFAIL, "cannot set lock in directory %s: check ownership",
  545. X          userdir);
  546. X    for (i = 0; link(template, LOCK) && i < MAXTRY; i++)
  547. X    (void) sleep(1);
  548. X    (void) unlink(template);
  549. X    if (i >= MAXTRY)
  550. X    error(EX_TEMPFAIL, "locked: %s", userdir);
  551. X
  552. X    /* Scan the user mail directory for the highest existing message number */
  553. X
  554. X    if ((dd = opendir(userdir)) == 0) {
  555. X    (void) unlink(LOCK);
  556. X    error(EX_TEMPFAIL, "opendir(\"%s\") failed: %m", userdir);
  557. X    }
  558. X    while (p = readdir(dd)) {
  559. X    if (sscanf(p->d_name + 1, "%d%c", &tmp, &junk) == 1 && tmp > seqno)
  560. X        seqno = tmp;
  561. X    }
  562. X
  563. X    /* clean up and terminate */
  564. X
  565. X    closedir(dd);
  566. X    (void) unlink(LOCK);
  567. X    return (seqno + 2);
  568. X}
  569. X
  570. X/* checkdir - check/update presence/ownership/protection of directory */
  571. X
  572. Xcheckdir(path, uid, gid, mode)
  573. Xchar   *path;
  574. Xint     uid;
  575. Xint     gid;
  576. Xint     mode;
  577. X{
  578. X    struct stat st;
  579. X
  580. X    /*
  581. X     * If a user mail directory does not exist, try to create it. Otherwise,
  582. X     * make sure it has sane permissions
  583. X     */
  584. X
  585. X    if (stat(path, &st) == -1) {        /* no directory */
  586. X    if (mkdir(path, mode))            /* try to create it */
  587. X        error(EX_TEMPFAIL, "cannot create directory %s: %m", path);
  588. X    if (chown(path, uid, gid))        /* set owner, group */
  589. X        error(EX_TEMPFAIL, "cannot chown directory %s: %m", path);
  590. X    } else {                    /* directory exists */
  591. X    if ((st.st_mode & S_IFMT) != S_IFDIR)    /* must be directory! */
  592. X        error(EX_TEMPFAIL, "%s should be a directory", path);
  593. X    if ((st.st_uid != uid || st.st_gid != gid)    /* check owner/group */
  594. X        &&chown(path, uid, gid))        /* correct owner, group */
  595. X        error(EX_TEMPFAIL, "cannot chown directory %s: %m", path);
  596. X    if ((st.st_mode & 0777) != mode        /* check permissions */
  597. X        && chmod(path, mode))        /* correct permissions */
  598. X        error(EX_TEMPFAIL, "cannot chmod %o directory %s: %m", mode, path);
  599. X    }
  600. X}
  601. X
  602. X/* error - print diagnostic and terminate */
  603. X
  604. X/* VARARGS */
  605. X
  606. Xvoid    error(va_alist) va_dcl
  607. X{
  608. X    va_list ap;
  609. X    register int exstat;
  610. X    register char *fmt;
  611. X    char    buf[BUFSIZ];
  612. X    int     err = errno;
  613. X
  614. X    /* Format the error message */
  615. X
  616. X    va_start(ap);
  617. X    exstat = va_arg(ap, int);            /* exit status */
  618. X    fmt = va_arg(ap, char *);            /* format string */
  619. X    (void) vsprintf(buf, percentm(fmt, err), ap);
  620. X    va_end(ap);
  621. X
  622. X    /* Write message to standard error stream */
  623. X
  624. X    (void) fprintf(stderr, "%s: %s\n", progname, buf);
  625. X
  626. X    /* Append the same message to system log */
  627. X
  628. X    (void) openlog("pc-mail", LOG_PID, LOG_MAIL);
  629. X    (void) syslog(LOG_WARNING, "%s", buf);
  630. X    (void) closelog();
  631. X
  632. X    /* Notify sendmail of the nature of the problem */
  633. X
  634. X    exit(exstat);
  635. X}
  636. X
  637. X#ifdef SYSV
  638. X
  639. X/* mkdir - create directory */
  640. X
  641. Xint     mkdir(dir, mode)
  642. Xchar   *dir;
  643. Xint     mode;
  644. X{
  645. X    char    cmd[BUFSIZ];
  646. X
  647. X    sprintf(cmd, "mkdir %s 2>&1 >/dev/null 2>&1 && chmod %o %s",
  648. X        dir, mode, dir);
  649. X    return (system(cmd));            /* does not set errno */
  650. X}
  651. X
  652. X#endif
  653. END_OF_FILE
  654. if test 10884 -ne `wc -c <'pc-mail.c'`; then
  655.     echo shar: \"'pc-mail.c'\" unpacked with wrong size!
  656. fi
  657. # end of 'pc-mail.c'
  658. fi
  659. if test -f 'pc-maild.c' -a "${1}" != "-c" ; then 
  660.   echo shar: Will not clobber existing file \"'pc-maild.c'\"
  661. else
  662. echo shar: Extracting \"'pc-maild.c'\" \(13746 characters\)
  663. sed "s/^X//" >'pc-maild.c' <<'END_OF_FILE'
  664. X/*++
  665. X/* NAME
  666. X/*    pc-maild 8
  667. X/* SUMMARY
  668. X/*    deliver unsent mail
  669. X/* PROJECT
  670. X/*    pc-mail
  671. X/* PACKAGE
  672. X/*    nfs
  673. X/* SYNOPSIS
  674. X/*    pc-maild [delay]
  675. X/* DESCRIPTION
  676. X/*    This program should be run on the nfs file server that exports
  677. X/*    mail directories to MS-DOS pc-mail users. It replaces the
  678. X/*    (MS-DOS -> UNIX) transmission function of the MS-DOS \fIcico\fR
  679. X/*    program.
  680. X/*
  681. X/*    The per-user mail directories (default: /var/spool/pc-mail/\fIuser\fR)
  682. X/*    are scanned for outgoing mail every \fIdelay\fR seconds (default: 300).
  683. X/*    When outgoing mail is found, it is sent through the UNIX rmail program
  684. X/*    (uucp mail interface) and the corresponding files are removed from the
  685. X/*    user\'s mail directory.
  686. X/*
  687. X/*    The program should run with root privileges. It will assume
  688. X/*    the (uid, gid) of the sending user before accessing mail files.
  689. X/* COMMANDS
  690. X/*    rmail(1), uucp mail interface program
  691. X/* FILES
  692. X/*    /usr/spool/pc-mail/\fIuser\fR/dNNNNN, mail message
  693. X/*    /usr/spool/pc-mail/\fIuser\fR/xNNNNN, recipients
  694. X/*    (NNNNN is the pc-mail "message id").
  695. X/* SEE ALSO
  696. X/*    pc-mail(1)
  697. X/* DIAGNOSTICS
  698. X/*    Errors found during initialization cause the program to
  699. X/*    terminate with a diagnostic on the standard error stream.
  700. X/*    All other errors are considered transient, i.e. if something
  701. X/*    fails, it is tried again at a later time.  Where possible,
  702. X/*    diagnostics are logged through the syslog facility.
  703. X/* BUGS
  704. X/*    Scanning mail directories is an inefficient way to detect
  705. X/*    unsent mail.
  706. X/* AUTHOR(S)
  707. X/*    W.Z. Venema
  708. X/*    Eindhoven University of Technology
  709. X/*    Department of Mathematics and Computer Science
  710. X/*    Den Dolech 2, P.O. Box 513, 5600 MB Eindhoven, The Netherlands
  711. X/* CREATION DATE
  712. X/*    Sun Oct 22 22:12:15 MED 1989
  713. X/* LAST MODIFICATION
  714. X/*    10/31/89 15:44:54
  715. X/* VERSION/RELEASE
  716. X/*    1.3
  717. X/*--*/
  718. X
  719. X#ifndef lint
  720. Xstatic char sccsid[] = "@(#) pc-maild.c 1.3 10/31/89 15:44:54";
  721. X
  722. X#endif
  723. X
  724. X /*
  725. X  * General return-value conventions:
  726. X  * 
  727. X  * int func():        0 means OK
  728. X  * 
  729. X  * stuff *func():    0 means error
  730. X  * 
  731. X  */
  732. X
  733. X#include <stdio.h>
  734. X#include <pwd.h>
  735. X#include <time.h>
  736. X#include <signal.h>
  737. X#include <sys/types.h>
  738. X#include <sys/stat.h>
  739. X
  740. X#ifdef SYSLOG
  741. X#include <syslog.h>
  742. X#else
  743. X#include "syslog.h"
  744. X#endif
  745. X
  746. X#ifdef SYSV
  747. X#include <sys/utsname.h>
  748. X#include <ndir.h>
  749. X#else
  750. X#include <sys/types.h>
  751. X#include <sys/dir.h>
  752. X#include <sgtty.h>
  753. X#endif
  754. X
  755. X#include "dosunix.h"
  756. X#include "util.h"
  757. X#include "mtime.h"
  758. X
  759. X/* Library functions */
  760. X
  761. Xextern char *strtok();
  762. Xextern char *strncpy();
  763. Xextern struct passwd *getpwnam();
  764. Xextern unsigned sleep();
  765. Xextern void exit();
  766. Xextern void _exit();
  767. Xextern struct tm *localtime();
  768. Xextern char *asctime();
  769. Xextern long time();
  770. X
  771. X/* Local defines, declarations */
  772. X
  773. X#ifndef    DELAY
  774. X#define    DELAY    300            /* default: scan every 5 minutes */
  775. X#endif
  776. X
  777. X#ifndef    MAILDIR
  778. X#define    MAILDIR    "/usr/spool/pc-mail"    /* default pc-mail directory tree */
  779. X#endif
  780. X
  781. X
  782. Xvoid    catchsig();
  783. Xvoid    finduser();
  784. Xchar   *getrcpt();
  785. Xchar   *fullname();
  786. X
  787. Xint     delay = DELAY;            /* the default delay */
  788. Xchar   *progname;            /* my process name */
  789. X
  790. X
  791. Xint     main(argc, argv)
  792. Xint     argc;
  793. Xchar  **argv;
  794. X{
  795. X    progname = *argv;
  796. X
  797. X    /* Sanity checks */
  798. X
  799. X#ifndef DEBUG
  800. X
  801. X    if (geteuid() != 0) {
  802. X    fprintf(stderr, "%s: must be run as root\n", progname);
  803. X    exit(1);
  804. X    }
  805. X#endif
  806. X
  807. X    /* Check for command-line delay argument */
  808. X
  809. X    if (argc > 1 && (delay = atoi(argv[1])) < 1)
  810. X    delay = DELAY;
  811. X
  812. X    /* Become a daemon process */
  813. X
  814. X#ifndef DEBUG
  815. X    disconnect();
  816. X#endif
  817. X
  818. X    /* Set up signal handling */
  819. X
  820. X    catchsig();
  821. X
  822. X    /* Enable syslogging */
  823. X
  824. X    (void) openlog(progname, LOG_PID, LOG_MAIL);
  825. X    syslog(LOG_WARNING, "daemon restarted");
  826. X
  827. X    /* Setup a decent environment */
  828. X
  829. X    if (putenv("PATH=/bin:/usr/bin:/usr/ucb") || putenv("IFS= \t\n")) {
  830. X    syslog(LOG_WARNING, "initialization failed (insufficient resources)");
  831. X    exit(1);
  832. X    }
  833. X    /* Enter the main loop */
  834. X
  835. X    finduser();
  836. X    /* NOTREACHED */
  837. X}
  838. X
  839. X/* finduser - repeatedly iterate over all pc-mail user directories */
  840. X
  841. Xvoid    finduser()
  842. X{
  843. X    register DIR *maildp;
  844. X    register struct direct *dp;
  845. X    register struct passwd *uinfo;
  846. X    MTIME  *dirtime;
  847. X    char    userdir[BUFSIZ];
  848. X    struct stat st;
  849. X
  850. X    /*
  851. X     * Ignore names that start with a period.
  852. X     *
  853. X     * Ignore names that do not correspond to a directory.
  854. X     * 
  855. X     * Ignore directories that did not change since the last time they were
  856. X     * known to hold no unsent mail.
  857. X     * 
  858. X     * Ignore directories that do not have a name equal to the login name of a
  859. X     * user.
  860. X     */
  861. X
  862. X    for (;;) {
  863. X    if ((e_chdir(MAILDIR) == 0) && (maildp = e_opendir(MAILDIR))) {
  864. X        while (dp = readdir(maildp)) {
  865. X        if ((dp->d_name[0] != '.')
  866. X            && (stat(dp->d_name, &st) == 0)
  867. X            && ((st.st_mode & S_IFMT) == S_IFDIR)
  868. X            && (st.st_mtime > (dirtime = mtime(dp->d_name))->time)
  869. X            && ((uinfo = getpwnam(dp->d_name)) != 0)) {
  870. X            (void) sprintf(userdir, "%s/%s", MAILDIR, dp->d_name);
  871. X            if (findmail(uinfo, userdir) == 0)
  872. X            dirtime->time = st.st_mtime;    /* say it was empty */
  873. X        }
  874. X        }
  875. X        closedir(maildp);            /* done with this user */
  876. X        (void) chdir("/");            /* be friendly */
  877. X    }
  878. X    (void) sleep(delay);            /* try again later */
  879. X    }
  880. X}
  881. X/* findmail - enter a user\'s mail directory and scan for unsent mail */
  882. X
  883. Xint     findmail(uinfo, userdir)
  884. Xstruct passwd *uinfo;
  885. Xchar   *userdir;
  886. X{
  887. X    register DIR *dd;
  888. X    register struct direct *p;
  889. X    int     seqno;
  890. X    static char xfile[BUFSIZ];        /* file with recipients */
  891. X    static char dfile[BUFSIZ];        /* file with mail message */
  892. X    int     found = 0;            /* no mail found yet */
  893. X
  894. X    /*
  895. X     * Use the fact that 'x' files (recipient addresses) are created later
  896. X     * than 'd' files (message body) when a pc user generates a message.
  897. X     * Extract the pc-mail message id from the file name and try to pipe the
  898. X     * message through the UNIX rmail command. All knowledge about pc-mail
  899. X     * file names resides in this function. Return zero if no unsent mail was
  900. X     * found.
  901. X     */
  902. X
  903. X    if ((e_chdir(userdir) == 0) && (dd = e_opendir(userdir))) {
  904. X    while (p = readdir(dd)) {
  905. X        if (*p->d_name == 'x' && sscanf(p->d_name + 1, "%d", &seqno) == 1) {
  906. X        (void) sprintf(xfile, "x%05d", seqno);    /* recipients */
  907. X        if (strcmp(p->d_name, xfile) == 0) {    /* ignore junk */
  908. X            (void) sprintf(dfile, "d%05d", seqno);
  909. X            pickup(uinfo, xfile, dfile);
  910. X            found = 1;            /* found unsent mail */
  911. X        }
  912. X        }
  913. X    }
  914. X    closedir(dd);
  915. X    (void) chdir(MAILDIR);
  916. X    }
  917. X    return (found);
  918. X}
  919. X
  920. X/* pickup - pick up one message from a user\'s mail directory */
  921. X
  922. Xpickup(uinfo, xfile, dfile)
  923. Xstruct passwd *uinfo;
  924. Xchar   *xfile;
  925. Xchar   *dfile;
  926. X
  927. X{
  928. X
  929. X    /*
  930. X     * Actual delivery must be done with the (uid, gid) of the sender, or the
  931. X     * From: lines will not be correct. Therefore, we do delivery in a child
  932. X     * process. This also avoid all kinds of nasty security problems. All
  933. X     * errors are considered non-fatal.
  934. X     */
  935. X
  936. X#ifdef DEBUG
  937. X    sendasuser(uinfo, xfile, dfile);        /* don't fork */
  938. X#else
  939. X    switch (e_fork()) {
  940. X    case -1:                    /* failure */
  941. X    break;
  942. X    case 0:                    /* child */
  943. X    sendasuser(uinfo, xfile, dfile);
  944. X    _exit(0);
  945. X    /* NOTREACHED */
  946. X    default:                    /* parent */
  947. X    (void) wait((int *) 0);
  948. X    break;
  949. X    }
  950. X#endif
  951. X}
  952. X
  953. X/* sendasuser - send mail through rmail(1), having (uid, gid) of sender */
  954. X
  955. Xsendasuser(uinfo, xfile, dfile)
  956. Xstruct passwd *uinfo;
  957. Xchar   *xfile;
  958. Xchar   *dfile;
  959. X{
  960. X    char   *dest;            /* recipient address(es) */
  961. X
  962. X    /*
  963. X     * User-specific mail files must be opened AFTER we have assumed the
  964. X     * (uid, gid) of the pc-mail user; this in order to avoid nasty security
  965. X     * holes.
  966. X     */
  967. X
  968. X    if ((setugid(uinfo) == 0)            /* assume proper (uid, gid) */
  969. X    &&(dest = getrcpt(uinfo, xfile))    /* extract recipients */
  970. X    &&(rmail(uinfo, dfile, dest) == 0)) {    /* pipe message through rmail */
  971. X    (void) u_unlink(uinfo, xfile);        /* recipients file */
  972. X    (void) u_unlink(uinfo, dfile);        /* message body file */
  973. X    }
  974. X}
  975. X
  976. X/* setugid - assume (uid, gid) of user */
  977. X
  978. Xint     setugid(uinfo)
  979. Xstruct passwd *uinfo;
  980. X{
  981. X    if (setgid(uinfo->pw_gid)) {
  982. X    syslog(LOG_WARNING, "setgid(%s) failed: %m", uinfo->pw_name);
  983. X    return (1);
  984. X    }
  985. X    if (setuid(uinfo->pw_uid)) {
  986. X    syslog(LOG_WARNING, "setuid(%s) failed: %m", uinfo->pw_name);
  987. X    return (1);
  988. X    } else {
  989. X    return (0);
  990. X    }
  991. X}
  992. X
  993. X/* getrcpt - extract recipient from user mail file */
  994. X
  995. Xchar   *getrcpt(uinfo, xfile)
  996. Xstruct passwd *uinfo;
  997. Xchar   *xfile;
  998. X{
  999. X    FILE   *xfp;            /* recipient file pointer */
  1000. X    static char dest[2 * BUFSIZ];    /* recipient names */
  1001. X    register char *ret;
  1002. X
  1003. X    if ((xfp = u_fopen(uinfo, xfile, "r")) == 0) {
  1004. X    return (0);
  1005. X    } else {
  1006. X    pc_wait(fileno(xfp));        /* let pc finish writing */
  1007. X    ret = dosgets(dest, sizeof(dest), xfp);
  1008. X    (void) fclose(xfp);
  1009. X    if (ret == 0)
  1010. X        syslog(LOG_WARNING, "no recipients specified in %s/%s",
  1011. X           uinfo->pw_name, xfile);
  1012. X    return (ret);
  1013. X    }
  1014. X}
  1015. X
  1016. X/* rmail - pipe a pc mail message through the UNIX rmail program */
  1017. X
  1018. Xint     rmail(uinfo, dfile, dest)
  1019. Xstruct passwd *uinfo;            /* originator */
  1020. Xchar   *dfile;                /* message file */
  1021. Xchar   *dest;                /* recipients */
  1022. X{
  1023. X    static char cmd[BUFSIZ * 2];    /* command + arguments */
  1024. X    FILE   *dfp;            /* source stream */
  1025. X    FILE   *pfp;            /* output stream */
  1026. X    int     ret;            /* return value, 0 if OK */
  1027. X    long    secs;            /* absolute UNIX time */
  1028. X    static char hostname[BUFSIZ];    /* our host name */
  1029. X
  1030. X    /*
  1031. X     * The UNIX rmail command needs a UUCP-style From_ line.
  1032. X     * 
  1033. X     * The To: and From: lines can be added for esthetical porposes.
  1034. X     * 
  1035. X     * Report communication failures with the rmail command. Error returns from
  1036. X     * rmail are ignored; they should be handled in sendmail.
  1037. X     */
  1038. X
  1039. X    if (dfp = u_fopen(uinfo, dfile, "r")) {    /* open message file */
  1040. X    sprintf(cmd, "rmail %s", dest);
  1041. X    if ((pfp = popen(cmd, "w")) == 0) {    /* invoke rmail... */
  1042. X        syslog(LOG_WARNING, "cannot invoke %.20s...: %m", rmail);
  1043. X        ret = 1;
  1044. X    } else {
  1045. X        secs = time((long *) 0);
  1046. X        (void) gethostname(hostname, sizeof(hostname));
  1047. X        fprintf(pfp, "From %s %.24s remote from %s\n", uinfo->pw_name,
  1048. X            asctime(localtime(&secs)),
  1049. X            hostname);            /* add UUCP From_ line */
  1050. X#ifdef    RFC822
  1051. X        rfc822hdr(uinfo, dest, pfp);    /* do RFC822 stuff */
  1052. X#endif
  1053. X        if (ret = dos2unix(dfp, pfp))    /* append message body */
  1054. X        syslog(LOG_WARNING, "write to rmail failed: %m");
  1055. X        (void) pclose(pfp);
  1056. X    }
  1057. X    (void) fclose(dfp);
  1058. X    }
  1059. X    return (ret);
  1060. X}
  1061. X
  1062. X/* rfc822hdr - generate subset of RFC822 header lines */
  1063. X
  1064. Xrfc822hdr(uinfo, dest, pfp)
  1065. Xregister struct passwd *uinfo;
  1066. Xchar   *dest;
  1067. Xregister FILE *pfp;
  1068. X{
  1069. X    char   *sep = " ,\t\r\n";
  1070. X    char   *name;
  1071. X
  1072. X    /*
  1073. X     * There are a few problems with this function. First of all, it destroys
  1074. X     * the dest argument. In the second place, putting each recipient on a
  1075. X     * separate To: header line is ugly.
  1076. X     */
  1077. X
  1078. X    fprintf(pfp, "From: %s (%s)\n", uinfo->pw_name,
  1079. X        fullname(uinfo));            /* add From: header line */
  1080. X    for (name = strtok(dest, sep); name; name = strtok((char *) 0, sep))
  1081. X    fprintf(pfp, "To: %s\n", name);        /* add To: header line */
  1082. X}
  1083. X
  1084. X/* fullname - extract full name from gecos field */
  1085. X
  1086. Xchar   *fullname(uinfo)
  1087. Xstruct passwd *uinfo;
  1088. X{
  1089. X    static char name[BUFSIZ];
  1090. X
  1091. X    /* This code assumes BSD-style gecos fields (name,stuff,stuff...) */
  1092. X
  1093. X    if (sscanf(uinfo->pw_gecos, "%[^,]", name) == 0)
  1094. X    name[0] = '\0';
  1095. X    return (name);
  1096. X}
  1097. X
  1098. X/* gotsig - caught a signal; terminate with diagnostic */
  1099. X
  1100. Xvoid    gotsig(sig)
  1101. Xint     sig;
  1102. X{
  1103. X    syslog(LOG_WARNING, "going down on signal %d", sig);
  1104. X    closelog();
  1105. X    exit(sig);
  1106. X}
  1107. X
  1108. X/* catchsig - catch some signals */
  1109. X
  1110. Xvoid    catchsig()
  1111. X{
  1112. X#ifdef    DEBUG
  1113. X    (void) signal(SIGHUP, gotsig);
  1114. X    (void) signal(SIGINT, gotsig);
  1115. X    (void) signal(SIGQUIT, gotsig);
  1116. X#else
  1117. X    (void) signal(SIGHUP, SIG_IGN);
  1118. X    (void) signal(SIGINT, SIG_IGN);
  1119. X    (void) signal(SIGQUIT, SIG_IGN);
  1120. X#endif
  1121. X    (void) signal(SIGBUS, gotsig);
  1122. X    (void) signal(SIGSEGV, gotsig);
  1123. X    (void) signal(SIGTERM, gotsig);
  1124. X}
  1125. X
  1126. X/* disconnect - become a daemon process */
  1127. X
  1128. Xdisconnect()
  1129. X{
  1130. X#ifndef    SYSV
  1131. X    int     fd;
  1132. X
  1133. X#endif
  1134. X
  1135. X    /* Get rid of the parent process */
  1136. X
  1137. X    switch (e_fork()) {
  1138. X    case -1:                    /* failure */
  1139. X    exit(1);
  1140. X    /* NOTREACHED */
  1141. X    default:
  1142. X    _exit(0);                /* parent */
  1143. X    /* NOTREACHED */
  1144. X    case 0:                    /* child */
  1145. X    break;
  1146. X    }
  1147. X
  1148. X    /* Get rid of the controlling terminal */
  1149. X
  1150. X    (void) close(0);
  1151. X    (void) close(1);
  1152. X    (void) close(2);
  1153. X#ifdef SYSV
  1154. X    (void) setpgrp();
  1155. X#else
  1156. X    if ((fd = open("/dev/tty", 0)) >= 0) {
  1157. X    (void) ioctl(fd, TIOCNOTTY, 0);
  1158. X    (void) close(fd);
  1159. X    }
  1160. X#endif
  1161. X}
  1162. X
  1163. X/* pc_wait - wait till the pc has finished writing a file */
  1164. X
  1165. Xpc_wait(fd)
  1166. Xint     fd;
  1167. X{
  1168. X    struct stat st;
  1169. X    long    oldsize = 0;
  1170. X
  1171. X    /*
  1172. X     * Repeatedly sleep one second until the file size does not change
  1173. X     * anymore.
  1174. X     * 
  1175. X     * At first sight, this does not seem to be a very robust algorithm. It is,
  1176. X     * however, sufficient. The pc sofware will first create a message file,
  1177. X     * then the file with recipient addresses. The pc-maild program, on the
  1178. X     * other hand, will read the recipient-address file first. If that file
  1179. X     * turns out to be empty, it will try again at a later time. So, the only
  1180. X     * time we may produce an incorrect result is under the following
  1181. X     * conditions:
  1182. X     * 
  1183. X     * (1) the file with recipient names is longer than the PC/NFS packet size
  1184. X     * or the pc\'s stdio buffer size.
  1185. X     * 
  1186. X     * (2) the network connection goes down for > 1 second after part of the
  1187. X     * data has arrived in the file with recipient addresses.
  1188. X     */
  1189. X
  1190. X    while (fstat(fd, &st) == 0 && oldsize != st.st_size) {
  1191. X    oldsize = st.st_size;
  1192. X    sleep(1);
  1193. X    }
  1194. X}
  1195. X
  1196. X#ifdef SYSV
  1197. X
  1198. X/* gethostname - BSD compatibility routine */
  1199. X
  1200. Xgethostname(name, len)
  1201. Xchar   *name;
  1202. Xint     len;
  1203. X{
  1204. X    struct utsname ut;
  1205. X
  1206. X    uname(&ut);
  1207. X    (void) strncpy(name, ut.nodename, len);
  1208. X    return (0);
  1209. X}
  1210. X
  1211. X#endif
  1212. END_OF_FILE
  1213. if test 13746 -ne `wc -c <'pc-maild.c'`; then
  1214.     echo shar: \"'pc-maild.c'\" unpacked with wrong size!
  1215. fi
  1216. # end of 'pc-maild.c'
  1217. fi
  1218. if test -f 'Makefile' -a "${1}" != "-c" ; then 
  1219.   echo shar: Will not clobber existing file \"'Makefile'\"
  1220. else
  1221. echo shar: Extracting \"'Makefile'\" \(4401 characters\)
  1222. sed "s/^X//" >'Makefile' <<'END_OF_FILE'
  1223. X# @(#) Makefile 1.5 11/19/89 13:53:47
  1224. X
  1225. X###############################
  1226. X# Start of configurable options. You will also have to do a `make depend'.
  1227. X
  1228. X# Compiler options.
  1229. X# -DSYSV is needed for system 5 release 2
  1230. X# -DRFC822 if you want the daemon to produce To: and From: header lines
  1231. X# -DSYSEXITS if your system has <sysexits.h>
  1232. X# -DSYSLOG if your system has a BSD 4.3-like syslog facility
  1233. X# -DSYSLOGFILE=\"/usr/spool/mqueue/syslog\" if you don't have BSD4.3-like syslog
  1234. X#    You will also have to create that file, with mode 666.
  1235. X#
  1236. X#BSD4.X: DEFS = -DRFC822 -DSYSEXITS -DSYSLOG
  1237. X#SYSVR2: DEFS = -DRFC822 -DSYSV -DSYSLOGFILE=\"/usr/spool/mqueue/syslog\" 
  1238. X
  1239. XDEFS    = -DRFC822 -DSYSEXITS -DSYSLOG
  1240. X
  1241. X# Location of pc-mail spool area
  1242. X
  1243. XMAILDIR    = /var/spool/pc-mail
  1244. X
  1245. X# How often the daeman will scan the pc-mail spool area for unsent mail.
  1246. X# This time interval can also be changed via the command line.
  1247. X
  1248. XDELAY    = 30
  1249. X
  1250. X# Some system-5 implementations have a separate library with BSD-compatible
  1251. X# directory access routines.
  1252. X#
  1253. X#LIBS    = -lndir
  1254. X
  1255. XLIBS    = 
  1256. X
  1257. X# Location of the pc-mail en pc-maild binaries
  1258. X
  1259. XEXEDIR    = /usr/local/lib
  1260. X
  1261. X# If you want to, where to install the manual pages
  1262. X
  1263. XMANDIR    = /usr/local/man/man8
  1264. X
  1265. X# End of configurable options
  1266. X#############################
  1267. X
  1268. XSHELL    = /bin/sh
  1269. XCFLAGS    = $(DEFS) -DDELAY=$(DELAY) -DMAILDIR=\"$(MAILDIR)\"
  1270. XARCHIVE    = sarch
  1271. XSOURCES    = README pc-mail.c pc-maild.c Makefile sysexits.h syslog.h \
  1272. X    syslog.c util.c util.h mtime.c mtime.h dosunix.c dosunix.h \
  1273. X    percentm.h percentm.c 
  1274. X
  1275. XPCMOBJ    = pc-mail.o syslog.o percentm.o dosunix.o
  1276. XPCMSRC    = pc-mail.c syslog.c percentm.c dosunix.c
  1277. X
  1278. XPCMDOBJ    = pc-maild.o syslog.o percentm.o dosunix.o util.o mtime.o
  1279. XPCMDSRC    = pc-maild.c syslog.c percentm.c dosunix.c util.c mtime.c
  1280. X
  1281. Xall:    pc-mail pc-maild
  1282. X
  1283. Xinstall: all
  1284. X    -mkdir $(MAILDIR)
  1285. X    chmod 755 $(MAILDIR)
  1286. X    cp pc-mail pc-maild $(EXEDIR)
  1287. X    chown root $(EXEDIR)/pc-mail
  1288. X    chmod 4755 $(EXEDIR)/pc-mail
  1289. X
  1290. Xinstallman: 
  1291. X    cp pc-mail.8 pc-maild.8 $(MANDIR)
  1292. X
  1293. Xpc-mail: $(PCMOBJ)
  1294. X    $(CC) $(CFLAGS) -o $@ $(PCMOBJ) $(LIBS)
  1295. X
  1296. Xpc-maild: $(PCMDOBJ)
  1297. X    $(CC) $(CFLAGS) -o $@ $(PCMDOBJ) $(LIBS)
  1298. X
  1299. Xlint:    lint1 lint2
  1300. X
  1301. Xlint1:    $(PCMSRC)
  1302. X    lint $(CFLAGS) $(PCMSRC)
  1303. X
  1304. Xlint2:    $(PCMDSRC)
  1305. X    lint $(CFLAGS) $(PCMDSRC)
  1306. X
  1307. Xshar:    $(SOURCES) pc-mail.8 pc-maild.8
  1308. X    @shar $(SOURCES) pc-mail.8 pc-maild.8
  1309. X
  1310. Xclean:
  1311. X    rm -f *.o core nohup.out
  1312. X
  1313. Xclobber: clean
  1314. X    rm -f pc-maild pc-mail *.8
  1315. X
  1316. Xarchive: $(SOURCES)
  1317. X    $(ARCHIVE) $?;
  1318. X    touch archive
  1319. X
  1320. Xdepend:    
  1321. X    (sed '1,/^# do not edit/!d' Makefile; \
  1322. X    for i in [a-z][a-z]*.c; do \
  1323. X        $(CC) -E $(CFLAGS) $$i | sed -n '/^# *1 *"\([^"]*\)".*/{;s//'`echo $$i|sed 's/c$$/o/'`':    \1/;p;}'; \
  1324. X    done)>$$$$ && mv $$$$ Makefile
  1325. X
  1326. X# do not edit below this line - it was create with `make depend'
  1327. Xdosunix.o:    dosunix.c
  1328. Xdosunix.o:    /usr/include/stdio.h
  1329. Xdosunix.o:    ./dosunix.h
  1330. Xmtime.o:    mtime.c
  1331. Xmtime.o:    /usr/include/syslog.h
  1332. Xmtime.o:    ./mtime.h
  1333. Xpc-mail.o:    pc-mail.c
  1334. Xpc-mail.o:    /usr/include/stdio.h
  1335. Xpc-mail.o:    /usr/include/sys/types.h
  1336. Xpc-mail.o:    /usr/include/sys/sysmacros.h
  1337. Xpc-mail.o:    /usr/include/sys/stat.h
  1338. Xpc-mail.o:    /usr/include/pwd.h
  1339. Xpc-mail.o:    /usr/include/varargs.h
  1340. Xpc-mail.o:    /usr/include/syslog.h
  1341. Xpc-mail.o:    /usr/include/sys/dir.h
  1342. Xpc-mail.o:    /usr/include/sysexits.h
  1343. Xpc-mail.o:    ./dosunix.h
  1344. Xpc-mail.o:    ./percentm.h
  1345. Xpc-maild.o:    pc-maild.c
  1346. Xpc-maild.o:    /usr/include/stdio.h
  1347. Xpc-maild.o:    /usr/include/pwd.h
  1348. Xpc-maild.o:    /usr/include/time.h
  1349. Xpc-maild.o:    /usr/include/signal.h
  1350. Xpc-maild.o:    /usr/include/vm/faultcode.h
  1351. Xpc-maild.o:    /usr/include/sys/types.h
  1352. Xpc-maild.o:    /usr/include/sys/sysmacros.h
  1353. Xpc-maild.o:    /usr/include/sys/stat.h
  1354. Xpc-maild.o:    /usr/include/syslog.h
  1355. Xpc-maild.o:    /usr/include/sys/types.h
  1356. Xpc-maild.o:    /usr/include/sys/dir.h
  1357. Xpc-maild.o:    /usr/include/sgtty.h
  1358. Xpc-maild.o:    /usr/include/sys/ioctl.h
  1359. Xpc-maild.o:    /usr/include/sys/ttychars.h
  1360. Xpc-maild.o:    /usr/include/sys/ttydev.h
  1361. Xpc-maild.o:    /usr/include/sys/ttold.h
  1362. Xpc-maild.o:    /usr/include/sys/ioccom.h
  1363. Xpc-maild.o:    /usr/include/sys/ttycom.h
  1364. Xpc-maild.o:    /usr/include/sys/filio.h
  1365. Xpc-maild.o:    /usr/include/sys/ioccom.h
  1366. Xpc-maild.o:    /usr/include/sys/sockio.h
  1367. Xpc-maild.o:    /usr/include/sys/ioccom.h
  1368. Xpc-maild.o:    ./dosunix.h
  1369. Xpc-maild.o:    ./util.h
  1370. Xpc-maild.o:    ./mtime.h
  1371. Xpercentm.o:    percentm.c
  1372. Xpercentm.o:    /usr/include/stdio.h
  1373. Xpercentm.o:    ./percentm.h
  1374. Xsyslog.o:    syslog.c
  1375. Xutil.o:    util.c
  1376. Xutil.o:    /usr/include/stdio.h
  1377. Xutil.o:    /usr/include/pwd.h
  1378. Xutil.o:    /usr/include/sys/types.h
  1379. Xutil.o:    /usr/include/sys/sysmacros.h
  1380. Xutil.o:    /usr/include/sys/dir.h
  1381. Xutil.o:    /usr/include/syslog.h
  1382. Xutil.o:    ./util.h
  1383. END_OF_FILE
  1384. if test 4401 -ne `wc -c <'Makefile'`; then
  1385.     echo shar: \"'Makefile'\" unpacked with wrong size!
  1386. fi
  1387. # end of 'Makefile'
  1388. fi
  1389. if test -f 'sysexits.h' -a "${1}" != "-c" ; then 
  1390.   echo shar: Will not clobber existing file \"'sysexits.h'\"
  1391. else
  1392. echo shar: Extracting \"'sysexits.h'\" \(972 characters\)
  1393. sed "s/^X//" >'sysexits.h' <<'END_OF_FILE'
  1394. X/*++
  1395. X/* NAME
  1396. X/*    sysexits 5
  1397. X/* SUMMARY
  1398. X/*    exit status codes for programs called by sendmail
  1399. X/* PROJECT
  1400. X/*    pc-mail
  1401. X/* PACKAGE
  1402. X/*    nfs
  1403. X/* SYNOPSIS
  1404. X/*    #include "sysexits.h"
  1405. X/* DESCRIPTION
  1406. X/* .nf
  1407. X
  1408. X /* sendmail-compatible exit status codes */
  1409. X
  1410. X#define    EX_OK        0
  1411. X#define EX_USAGE    64
  1412. X#define EX_DATAERR    65
  1413. X#define EX_NOINPUT    66
  1414. X#define EX_NOUSER    67
  1415. X#define EX_NOHOST    68
  1416. X#define EX_UNAVAILABLE    69
  1417. X#define EX_SOFTWARE    70
  1418. X#define EX_OSERR    71
  1419. X#define EX_OSFILE    72
  1420. X#define EX_CANTCREAT    73
  1421. X#define EX_IOERR    74
  1422. X#define EX_TEMPFAIL    75
  1423. X#define EX_PROTOCOL    76
  1424. X#define EX_NOPERM    77
  1425. X/* AUTHOR(S)
  1426. X/*    Wietse Z. Venema
  1427. X/*    Eindhoven University of Technology
  1428. X/*    Department of Mathematics and Computer Science
  1429. X/*    Den Dolech 2, P.O. Box 513, 5600 MB Eindhoven, The Netherlands
  1430. X/*
  1431. X/*    These codes were actually defined by Eric Allman, the originator
  1432. X/*    of the sendmail program.
  1433. X/* CREATION DATE
  1434. X/*    Sun Oct 29 16:03:19 MET 1989
  1435. X/* LAST MODIFICATION
  1436. X/*    10/29/89 22:29:47
  1437. X/* VERSION/RELEASE
  1438. X/*    1.1
  1439. X/*--*/
  1440. X
  1441. END_OF_FILE
  1442. if test 972 -ne `wc -c <'sysexits.h'`; then
  1443.     echo shar: \"'sysexits.h'\" unpacked with wrong size!
  1444. fi
  1445. # end of 'sysexits.h'
  1446. fi
  1447. if test -f 'syslog.h' -a "${1}" != "-c" ; then 
  1448.   echo shar: Will not clobber existing file \"'syslog.h'\"
  1449. else
  1450. echo shar: Extracting \"'syslog.h'\" \(698 characters\)
  1451. sed "s/^X//" >'syslog.h' <<'END_OF_FILE'
  1452. X/*++
  1453. X/* NAME
  1454. X/*    syslog 5
  1455. X/* SUMMARY
  1456. X/*    surrogate BSD4.3 syslog facility
  1457. X/* PROJECT
  1458. X/*    pc-mail
  1459. X/* PACKAGE
  1460. X/*    nfs
  1461. X/* SYNOPSIS
  1462. X/*    include "syslog.h"
  1463. X/* DESCRIPTION
  1464. X/* .nf
  1465. X
  1466. X /* Do nothing if we already have <syslog.h> */
  1467. X
  1468. X#ifndef SYSLOG
  1469. X
  1470. X /* various constants */
  1471. X
  1472. X#define    LOG_PID        1
  1473. X#define    LOG_MAIL    1
  1474. X#define    LOG_WARNING    1
  1475. X
  1476. Xextern  openlog();
  1477. Xextern  syslog();
  1478. Xextern  closelog();
  1479. X
  1480. X#endif
  1481. X/* AUTHOR(S)
  1482. X/*    Wietse Z. Venema
  1483. X/*    Eindhoven University of Technology
  1484. X/*    Department of Mathematics and Computer Science
  1485. X/*    Den Dolech 2, P.O. Box 513, 5600 MB Eindhoven, The Netherlands
  1486. X/* CREATION DATE
  1487. X/*    Sun Oct 29 15:12:57 MET 1989
  1488. X/* LAST MODIFICATION
  1489. X/*    10/29/89 22:29:50
  1490. X/* VERSION/RELEASE
  1491. X/*    1.1
  1492. X/*--*/
  1493. X
  1494. END_OF_FILE
  1495. if test 698 -ne `wc -c <'syslog.h'`; then
  1496.     echo shar: \"'syslog.h'\" unpacked with wrong size!
  1497. fi
  1498. # end of 'syslog.h'
  1499. fi
  1500. if test -f 'syslog.c' -a "${1}" != "-c" ; then 
  1501.   echo shar: Will not clobber existing file \"'syslog.c'\"
  1502. else
  1503. echo shar: Extracting \"'syslog.c'\" \(2657 characters\)
  1504. sed "s/^X//" >'syslog.c' <<'END_OF_FILE'
  1505. X/*++
  1506. X/* NAME
  1507. X/*    syslog 3
  1508. X/* SUMMARY
  1509. X/*    surrogate BSD4.3 syslog facility
  1510. X/* PROJECT
  1511. X/*    pc-mail
  1512. X/* PACKAGE
  1513. X/*    nfs
  1514. X/* SYNOPSIS
  1515. X/*    include "syslog.h"
  1516. X/*
  1517. X/*    openlog(name, logopt, facility)
  1518. X/*    char *name;
  1519. X/*    int logopt;
  1520. X/*    int facility;
  1521. X/*
  1522. X/*    syslog(priority, format, arguments)
  1523. X/*    int priority;
  1524. X/*    char *format;
  1525. X/*
  1526. X/*    closelog()
  1527. X/* DESCRIPTION
  1528. X/*    These functions emulate the BSD4.3 syslog(3) facility. Output is
  1529. X/*    written to a system logfile (default /usr/spool/mqueue/syslog).
  1530. X/*    That file should have mode 666 (i.e. read/write access permitted
  1531. X/*    for everyone).
  1532. X/*
  1533. X/*    syslog() tries to output the log entry as one big chunk.
  1534. X/* FILES
  1535. X/*    /usr/spool/mqueue/syslog, system logfile
  1536. X/* SEE ALSO
  1537. X/*    percentm(3), interprets "%m" sequences in syslog format strings.
  1538. X/* BUGS
  1539. X/*    The functions use the stdio package. This may cause the program to
  1540. X/*    grow unexpectedly.
  1541. X/* AUTHOR(S)
  1542. X/*    Wietse Z. Venema
  1543. X/*    Eindhoven University of Technology
  1544. X/*    Department of Mathematics and Computer Science
  1545. X/*    Den Dolech 2, P.O. Box 513, 5600 MB Eindhoven, The Netherlands
  1546. X/* CREATION DATE
  1547. X/*    Sun Oct 29 15:12:57 MET 1989
  1548. X/* LAST MODIFICATION
  1549. X/*    10/29/89 22:58:33
  1550. X/* VERSION/RELEASE
  1551. X/*    1.2
  1552. X/*--*/
  1553. X
  1554. X#ifndef SYSLOG
  1555. X
  1556. X#ifndef lint
  1557. Xstatic char sccsid[] = "@(#) syslog.c 1.2 10/29/89 22:58:33";
  1558. X
  1559. X#endif
  1560. X
  1561. X#include <stdio.h>
  1562. X#include <varargs.h>
  1563. X#include <time.h>
  1564. X#include "percentm.h"
  1565. X
  1566. Xextern struct tm *localtime();
  1567. Xextern char *asctime();
  1568. Xextern long time();
  1569. Xextern int errno;
  1570. X
  1571. X#ifndef SYSLOGFILE
  1572. X#define    SYSLOGFILE    "/usr/spool/mqueue/syslog"
  1573. X#endif
  1574. X
  1575. Xstatic char *logname;
  1576. X
  1577. X/* openlog - initialize syslog facility; ignores all but the "name" argument */
  1578. X
  1579. X/* ARGSUSED */
  1580. X
  1581. Xopenlog(name, logopt, facility)
  1582. Xchar   *name;
  1583. Xint     logopt;
  1584. Xint     facility;
  1585. X{
  1586. X    logname = name;                /* ignore rest */
  1587. X}
  1588. X
  1589. X/* syslog - append entry to system log */
  1590. X
  1591. X/* VARARGS */
  1592. X
  1593. Xsyslog(va_alist)
  1594. Xva_dcl
  1595. X{
  1596. X    va_list ap;
  1597. X    char   *fmt;
  1598. X    char   *percentm();
  1599. X    long    secs;
  1600. X    char   *date;
  1601. X    FILE   *fp;
  1602. X    int     err = errno;
  1603. X    static char buf[BUFSIZ];
  1604. X
  1605. X    if (fp = fopen(SYSLOGFILE, "a")) {
  1606. X
  1607. X    /* Format the time stamp */
  1608. X
  1609. X    secs = time((long *) 0);
  1610. X    date = asctime(localtime(&secs));
  1611. X    (void) sprintf(buf, "%2.2s-%3.3s-%2.2s %8.8s %s: ",
  1612. X               date + 8, date + 4, date + 22, date + 11, logname);
  1613. X
  1614. X    /* Format the actual message */
  1615. X
  1616. X    va_start(ap);
  1617. X    (void) va_arg(ap, int);            /* skip priority */
  1618. X    fmt = va_arg(ap, char *);
  1619. X    (void) vsprintf(buf + strlen(buf), percentm(fmt, err), ap);
  1620. X    va_end(ap);
  1621. X
  1622. X    /* Try to ouput the log entry as one big chunk */
  1623. X
  1624. X    (void) fprintf(fp, "%s\n", buf);
  1625. X    (void) fclose(fp);
  1626. X    }
  1627. X}
  1628. X
  1629. X/* closelog - a real dummy */
  1630. X
  1631. Xcloselog()
  1632. X{
  1633. X    /* no-op */
  1634. X}
  1635. X
  1636. X#endif                    /* SYSLOG */
  1637. X
  1638. END_OF_FILE
  1639. if test 2657 -ne `wc -c <'syslog.c'`; then
  1640.     echo shar: \"'syslog.c'\" unpacked with wrong size!
  1641. fi
  1642. # end of 'syslog.c'
  1643. fi
  1644. if test -f 'util.c' -a "${1}" != "-c" ; then 
  1645.   echo shar: Will not clobber existing file \"'util.c'\"
  1646. else
  1647. echo shar: Extracting \"'util.c'\" \(2780 characters\)
  1648. sed "s/^X//" >'util.c' <<'END_OF_FILE'
  1649. X/*++
  1650. X/* NAME
  1651. X/*    util 3
  1652. X/* SUMMARY
  1653. X/*    wrappers around standard library functions
  1654. X/* PROJECT
  1655. X/*    pc-mail
  1656. X/* PACKAGE
  1657. X/*    nfs
  1658. X/* SYNOPSIS
  1659. X/*    #include <stdio.h>
  1660. X/*    #include <pwd.h>
  1661. X/*    #include <directory_access_stuff.h>
  1662. X/*
  1663. X/*    FILE *u_fopen(uinfo,path,mode)
  1664. X/*    struct passwd *uinfo;
  1665. X/*    char *path;
  1666. X/*    char *mode;
  1667. X/*
  1668. X/*    int u_unlink(uinfo, path)
  1669. X/*    struct passwd *uinfo;
  1670. X/*    char *path;
  1671. X/*
  1672. X/*    DIR *e_opendir(path)
  1673. X/*    char *path;
  1674. X/*
  1675. X/*    int e_chdir(path)
  1676. X/*    char *path;
  1677. X/*
  1678. X/*    int e_fork()
  1679. X/* DESCRIPTION
  1680. X/*    These functions are wrappers around some standard library functions.
  1681. X/*    In case of problems, they append an entry to the system log (with
  1682. X/*    priority LOG_WARNING). The \fIuinfo\fR argument specifies the owner
  1683. X/*    of the mail subdirectory in which the problem occurred.
  1684. X/* SEE ALSO
  1685. X/*    syslog(3)
  1686. X/* DIAGNOSTICS
  1687. X/*    Diagnostics are logged via the syslog package; error return values
  1688. X/*    are identical to those of the underlying library functions.
  1689. X/* AUTHOR(S)
  1690. X/*    Wietse Z. Venema
  1691. X/*    Eindhoven University of Technology
  1692. X/*    Department of Mathematics and Computer Science
  1693. X/*    Den Dolech 2, P.O. Box 513, 5600 MB Eindhoven, The Netherlands
  1694. X/* CREATION DATE
  1695. X/*    Sun Oct 29 16:21:02 MET 1989
  1696. X/* LAST MODIFICATION
  1697. X/*    10/29/89 22:29:53
  1698. X/* VERSION/RELEASE
  1699. X/*    1.1
  1700. X/*--*/
  1701. X
  1702. X#ifndef lint
  1703. Xstatic char sccsid[] = "@(#) util.c 1.1 10/29/89 22:29:53";
  1704. X
  1705. X#endif
  1706. X
  1707. X#include <stdio.h>
  1708. X#include <pwd.h>
  1709. X
  1710. X#ifdef SYSV
  1711. X#include <ndir.h>
  1712. X#else
  1713. X#include <sys/types.h>
  1714. X#include <sys/dir.h>
  1715. X#endif
  1716. X
  1717. X#ifdef SYSLOG
  1718. X#include <syslog.h>
  1719. X#else
  1720. X#include "syslog.h"
  1721. X#endif
  1722. X
  1723. X#include "util.h"            /* consistency check */
  1724. X
  1725. X/* u_fopen - open file in user directory, log any errors */
  1726. X
  1727. XFILE   *u_fopen(uinfo, file, mode)
  1728. Xstruct passwd *uinfo;
  1729. Xchar   *file;
  1730. Xchar   *mode;
  1731. X{
  1732. X    register FILE *fp;
  1733. X
  1734. X    if ((fp = fopen(file, mode)) == 0)
  1735. X    syslog(LOG_WARNING, "cannot open %s/%s: %m", uinfo->pw_name, file);
  1736. X    return (fp);
  1737. X}
  1738. X
  1739. X/* u_unlink - unlink file in user directory, log any errors */
  1740. X
  1741. Xint     u_unlink(uinfo, file)
  1742. Xstruct passwd *uinfo;
  1743. Xchar   *file;
  1744. X{
  1745. X    register int stat;
  1746. X
  1747. X    if (stat = unlink(file))
  1748. X    syslog(LOG_WARNING, "cannot unlink %s/%s: %m", uinfo->pw_name, file);
  1749. X    return (stat);
  1750. X}
  1751. X
  1752. X/* e_opendir - open directory, log any errors */
  1753. X
  1754. XDIR    *e_opendir(path)
  1755. Xchar   *path;
  1756. X{
  1757. X    register DIR *dd;
  1758. X
  1759. X    if ((dd = opendir(path)) == 0)
  1760. X    syslog(LOG_WARNING, "cannot open directory %s: %m", path);
  1761. X    return (dd);
  1762. X}
  1763. X
  1764. X/* e_chdir - change directory, log any errors */
  1765. X
  1766. Xint     e_chdir(path)
  1767. Xchar   *path;
  1768. X{
  1769. X    register int ret;
  1770. X
  1771. X    if (ret = chdir(path))
  1772. X    syslog(LOG_WARNING, "cannot chdir to directory %s: %m", path);
  1773. X    return (ret);
  1774. X}
  1775. X
  1776. X/* e_fork - do a fork(), log any errors */
  1777. X
  1778. Xint     e_fork()
  1779. X{
  1780. X    register int stat;
  1781. X
  1782. X    if ((stat = fork()) == -1)
  1783. X    syslog(LOG_WARNING, "fork() failed: %m");
  1784. X    return (stat);
  1785. X}
  1786. X
  1787. END_OF_FILE
  1788. if test 2780 -ne `wc -c <'util.c'`; then
  1789.     echo shar: \"'util.c'\" unpacked with wrong size!
  1790. fi
  1791. # end of 'util.c'
  1792. fi
  1793. if test -f 'util.h' -a "${1}" != "-c" ; then 
  1794.   echo shar: Will not clobber existing file \"'util.h'\"
  1795. else
  1796. echo shar: Extracting \"'util.h'\" \(1060 characters\)
  1797. sed "s/^X//" >'util.h' <<'END_OF_FILE'
  1798. X/*++
  1799. X/* NAME
  1800. X/*    util 3
  1801. X/* SUMMARY
  1802. X/*    wrappers around standard library functions
  1803. X/* PROJECT
  1804. X/*    pc-mail
  1805. X/* PACKAGE
  1806. X/*    nfs
  1807. X/* SYNOPSIS
  1808. X/*    #include <stdio.h>
  1809. X/*    #include <pwd.h>
  1810. X/*    #include "util.h"
  1811. X/* DESCRIPTION
  1812. X/* .nf
  1813. X
  1814. X /* Anticipate on ANSI-compatible compilers */
  1815. X
  1816. X#ifdef __STDC__
  1817. XFILE   *u_fopen(struct passwd * user, char *file, char *mode);
  1818. Xint     u_unlink(char *file);
  1819. XDIR    *e_opendir(char *path);
  1820. Xint     e_chdir(char *path);
  1821. Xint     e_fork(void);
  1822. X
  1823. X#else
  1824. XFILE   *u_fopen();            /* open file, log any errors */
  1825. Xint     u_unlink();            /* unlink file, log any errors */
  1826. XDIR    *e_opendir();            /* open directory, log any errors */
  1827. Xint     e_chdir();            /* change directory, log any errors */
  1828. Xint     e_fork();            /* fork, log any errors */
  1829. X
  1830. X#endif
  1831. X/* AUTHOR(S)
  1832. X/*    Wietse Z. Venema
  1833. X/*    Eindhoven University of Technology
  1834. X/*    Department of Mathematics and Computer Science
  1835. X/*    Den Dolech 2, P.O. Box 513, 5600 MB Eindhoven, The Netherlands
  1836. X/* CREATION DATE
  1837. X/*    Sun Oct 29 16:21:02 MET 1989
  1838. X/* LAST MODIFICATION
  1839. X/*    10/29/89 22:29:55
  1840. X/* VERSION/RELEASE
  1841. X/*    1.1
  1842. X/*--*/
  1843. X
  1844. END_OF_FILE
  1845. if test 1060 -ne `wc -c <'util.h'`; then
  1846.     echo shar: \"'util.h'\" unpacked with wrong size!
  1847. fi
  1848. # end of 'util.h'
  1849. fi
  1850. if test -f 'mtime.c' -a "${1}" != "-c" ; then 
  1851.   echo shar: Will not clobber existing file \"'mtime.c'\"
  1852. else
  1853. echo shar: Extracting \"'mtime.c'\" \(2331 characters\)
  1854. sed "s/^X//" >'mtime.c' <<'END_OF_FILE'
  1855. X/*++
  1856. X/* NAME
  1857. X/*    mtime 3
  1858. X/* SUMMARY
  1859. X/*    maintain modification times of files
  1860. X/* PROJECT
  1861. X/*    pc-mail
  1862. X/* PACKAGE
  1863. X/*    nfs
  1864. X/* SYNOPSIS
  1865. X/*    #include "mtime.h"
  1866. X/*
  1867. X/*    MTIME *mtime(path)
  1868. X/*    char *path;
  1869. X/* DESCRIPTION
  1870. X/*    mtime() maintains a table of modification times of files.
  1871. X/*    If a new file name is given, a modification time of 0 is
  1872. X/*    assumed (the UNIX equivalent of "a very long time ago").
  1873. X/*
  1874. X/*    If, for whatever reason, no memory can be allocated to update the
  1875. X/*    symbol table, a dummy entry is returned with modification time of 0.
  1876. X/* DIAGNOSTICS
  1877. X/*    Diagnostics are logged with the syslog(3) facility. The program
  1878. X/*    tries to continue to run as long as possible.
  1879. X/* BUGS
  1880. X/*    The dummy entry is stored in static memory; its value may be
  1881. X/*    overwritten an any time.
  1882. X/* AUTHOR(S)
  1883. X/*    Wietse Z. Venema
  1884. X/*    Eindhoven University of Technology
  1885. X/*    Department of Mathematics and Computer Science
  1886. X/*    Den Dolech 2, P.O. Box 513, 5600 MB Eindhoven, The Netherlands
  1887. X/* CREATION DATE
  1888. X/*    Sun Oct 29 15:48:01 MET 1989
  1889. X/* LAST MODIFICATION DATE
  1890. X/*    10/29/89 22:29:56
  1891. X/* VERSION/RELEASE
  1892. X/*    1.1
  1893. X/*--*/
  1894. X
  1895. X#ifndef lint
  1896. Xstatic char sccsid[] = "@(#) mtime.c 1.1 10/29/89 22:29:56";
  1897. X
  1898. X#endif
  1899. X
  1900. X#ifdef SYSLOG
  1901. X#include <syslog.h>
  1902. X#else
  1903. X#include "syslog.h"
  1904. X#endif
  1905. X
  1906. X#include "mtime.h"
  1907. X
  1908. Xextern char *malloc();
  1909. Xextern char *strcpy();
  1910. X
  1911. XMTIME  *mtime_tree;            /* head of symbol table */
  1912. X
  1913. X/* findtime - actual symbol-table access routine */
  1914. X
  1915. XMTIME  *findtime(path, tree)
  1916. Xregister char *path;
  1917. Xregister MTIME *tree;
  1918. X{
  1919. X    register int direct;
  1920. X    static MTIME dummy;
  1921. X
  1922. X    /*
  1923. X     * We use a trivial binary-tree storage scheme. If we cannot get memory
  1924. X     * for whatever reason, produce a dummy result. This means we will always
  1925. X     * believe that a file has changed. My first excercise in "graceful
  1926. X     * degradation".
  1927. X     */
  1928. X
  1929. X    if (tree == 0) {                /* new file */
  1930. X    if ((tree = (MTIME *) malloc(sizeof(MTIME))) == 0
  1931. X        || (tree->path = malloc(strlen(path) + 1)) == 0) {
  1932. X        syslog(LOG_WARNING, "memory allocation failed");
  1933. X        dummy.time = 0;
  1934. X        tree = &dummy;
  1935. X    } else {
  1936. X        (void) strcpy(tree->path, path);
  1937. X        tree->time = 0;
  1938. X        tree->left = tree->rite = 0;
  1939. X    }
  1940. X    } else if ((direct = strcmp(path, tree->path)) < 0) {
  1941. X    tree->left = findtime(path, tree->left);
  1942. X    } else if (direct > 0) {
  1943. X    tree->rite = findtime(path, tree->rite);
  1944. X    }
  1945. X    return (tree);
  1946. X}
  1947. X
  1948. END_OF_FILE
  1949. if test 2331 -ne `wc -c <'mtime.c'`; then
  1950.     echo shar: \"'mtime.c'\" unpacked with wrong size!
  1951. fi
  1952. # end of 'mtime.c'
  1953. fi
  1954. if test -f 'mtime.h' -a "${1}" != "-c" ; then 
  1955.   echo shar: Will not clobber existing file \"'mtime.h'\"
  1956. else
  1957. echo shar: Extracting \"'mtime.h'\" \(943 characters\)
  1958. sed "s/^X//" >'mtime.h' <<'END_OF_FILE'
  1959. X/*++
  1960. X/* NAME
  1961. X/*    mtime 5
  1962. X/* SUMMARY
  1963. X/*    maintain modification times of files
  1964. X/* PROJECT
  1965. X/*    pc-mail
  1966. X/* PACKAGE
  1967. X/*    nfs
  1968. X/* SYNOPSIS
  1969. X/*    #include "mtime.h"
  1970. X/* DESCRIPTION
  1971. X/* .nf
  1972. X
  1973. X /* structure of one symbol-table entry */
  1974. X
  1975. Xtypedef struct MTIME {
  1976. X    char   *path;            /* key */
  1977. X    long    time;            /* value */
  1978. X    struct MTIME *left;            /* left subtree */
  1979. X    struct MTIME *rite;            /* right subtree */
  1980. X}       MTIME;
  1981. X
  1982. X /* client interface */
  1983. X
  1984. X#define mtime(path)    (mtime_tree = findtime(path,mtime_tree))
  1985. X
  1986. X /* actual interface */
  1987. X
  1988. Xextern MTIME *mtime_tree;        /* head of symbol table */
  1989. XMTIME  *findtime();            /* actual access function */
  1990. X
  1991. X/* AUTHOR(S)
  1992. X/*    Wietse Z. Venema
  1993. X/*    Eindhoven University of Technology
  1994. X/*    Department of Mathematics and Computer Science
  1995. X/*    Den Dolech 2, P.O. Box 513, 5600 MB Eindhoven, The Netherlands
  1996. X/* CREATION DATE
  1997. X/*    Sun Oct 29 15:48:01 MET 1989
  1998. X/* LAST MODIFICATION DATE
  1999. X/*    10/29/89 22:29:58
  2000. X/* VERSION/RELEASE
  2001. X/*    1.1
  2002. X/*--*/
  2003. X
  2004. END_OF_FILE
  2005. if test 943 -ne `wc -c <'mtime.h'`; then
  2006.     echo shar: \"'mtime.h'\" unpacked with wrong size!
  2007. fi
  2008. # end of 'mtime.h'
  2009. fi
  2010. if test -f 'dosunix.c' -a "${1}" != "-c" ; then 
  2011.   echo shar: Will not clobber existing file \"'dosunix.c'\"
  2012. else
  2013. echo shar: Extracting \"'dosunix.c'\" \(2720 characters\)
  2014. sed "s/^X//" >'dosunix.c' <<'END_OF_FILE'
  2015. X/*++
  2016. X/* NAME
  2017. X/*    dosunix 3
  2018. X/* SUMMARY
  2019. X/*    UNIX <-> MS-DOS text format conversion
  2020. X/* PROJECT
  2021. X/*    pc-mail
  2022. X/* PACKAGE
  2023. X/*    nfs
  2024. X/* SYNOPSIS
  2025. X/*    #include <stdio.h>
  2026. X/*    #include "dosunix.h"
  2027. X/*
  2028. X/*    int dos2unix(ifp, ofp)
  2029. X/*    FILE *ifp;
  2030. X/*    FILE *ofp;
  2031. X/*
  2032. X/*    int unix2dos(ifp, ofp)
  2033. X/*    FILE *ifp;
  2034. X/*    FILE *ofp;
  2035. X/*
  2036. X/*    char *dosgets(buf, len, fp)
  2037. X/*    char *buf;
  2038. X/*    unsigned len;
  2039. X/*    FILE *fp;
  2040. X/* DESCRIPTION
  2041. X/*    dos2unix() converts an MS-DOS text stream (with cr/lf-delimited
  2042. X/*    lines) to a UNIX style stream (with lf-delimited lines).
  2043. X/*
  2044. X/*    unix2dos() performs the opposite function as dos2unix().
  2045. X/*
  2046. X/*    dosgets() reads one line from the designated stream and strips
  2047. X/*    off any cr of lf characters.
  2048. X/* DIAGNOSTICS
  2049. X/*    dos2unix(), unix2dos() return a nonzero value if an error was detected.
  2050. X/*
  2051. X/*    dosgets() returns (char *) 0 if it could not read any data.
  2052. X/* BUGS
  2053. X/*    Very long lines will be broken; Ctrl-Z in MS-DOS files is not
  2054. X/*    given special treatment, nor will it be added to the end of
  2055. X/*    MS-DOS files.
  2056. X/* AUTHOR(S)
  2057. X/*    Wietse Z. Venema
  2058. X/*    Eindhoven University of Technology
  2059. X/*    Department of Mathematics and Computer Science
  2060. X/*    Den Dolech 2, P.O. Box 513, 5600 MB Eindhoven, The Netherlands
  2061. X/* CREATION DATE
  2062. X/*    Sun Oct 29 16:41:50 MET 1989
  2063. X/* LAST MODIFICATION
  2064. X/*    10/29/89 22:30:00
  2065. X/* VERSION/RELEASE
  2066. X/*    1.1
  2067. X/*--*/
  2068. X
  2069. X#ifndef lint
  2070. Xstatic char sccsid[] = "@(#) dosunix.c 1.1 10/29/89 22:30:00";
  2071. X
  2072. X#endif
  2073. X
  2074. X#include <stdio.h>
  2075. X#include "dosunix.h"            /* consistency check */
  2076. X
  2077. Xextern char *strchr();
  2078. Xextern char *fgets();
  2079. X
  2080. X/* unix2dos - copy UNIX-format stream to MS-DOS-format stream */
  2081. X
  2082. Xint     unix2dos(ifp, ofp)
  2083. XFILE   *ifp;
  2084. XFILE   *ofp;
  2085. X{
  2086. X    static char buf[BUFSIZ];
  2087. X    register int end;
  2088. X
  2089. X    while (fgets(buf, sizeof(buf), ifp)) {
  2090. X    if (buf[end = strlen(buf) - 1] == '\n') {
  2091. X        buf[end] = '\r';
  2092. X        (void) fputs(buf, ofp);
  2093. X        (void) putc('\n', ofp);
  2094. X    } else {
  2095. X        (void) fputs(buf, ofp);
  2096. X    }
  2097. X    }
  2098. X    return (fflush(ofp) || ferror(ofp) || feof(ofp));
  2099. X}
  2100. X
  2101. X/* dos2unix - copy MS-DOS-format text stream to UNIX-format text stream */
  2102. X
  2103. Xint     dos2unix(dfp, pfp)
  2104. Xregister FILE *dfp;
  2105. Xregister FILE *pfp;
  2106. X{
  2107. X    static char msgbuf[BUFSIZ];        /* copy buffer */
  2108. X
  2109. X    while (dosgets(msgbuf, sizeof(msgbuf), dfp)) {
  2110. X    (void) fputs(msgbuf, pfp);
  2111. X    (void) putc('\n', pfp);
  2112. X    }
  2113. X    return (fflush(pfp) || ferror(pfp) || feof(pfp));
  2114. X}
  2115. X
  2116. X/* dosgets - read one line from DOS-format text stream; strip cr and lf */
  2117. X
  2118. Xchar   *dosgets(buf, len, fp)
  2119. Xregister char *buf;
  2120. Xunsigned len;
  2121. Xregister FILE *fp;
  2122. X{
  2123. X    register char *cp;
  2124. X    register char *ret;
  2125. X
  2126. X    /* Lines with >= len characters will be broken */
  2127. X
  2128. X    if ((ret = fgets(buf, len, fp))
  2129. X    && ((cp = strchr(buf, '\r')) || (cp = strchr(buf, '\n'))))
  2130. X    *cp = '\0';                /* strip cr or lf */
  2131. X    return (ret);
  2132. X}
  2133. X
  2134. END_OF_FILE
  2135. if test 2720 -ne `wc -c <'dosunix.c'`; then
  2136.     echo shar: \"'dosunix.c'\" unpacked with wrong size!
  2137. fi
  2138. # end of 'dosunix.c'
  2139. fi
  2140. if test -f 'dosunix.h' -a "${1}" != "-c" ; then 
  2141.   echo shar: Will not clobber existing file \"'dosunix.h'\"
  2142. else
  2143. echo shar: Extracting \"'dosunix.h'\" \(779 characters\)
  2144. sed "s/^X//" >'dosunix.h' <<'END_OF_FILE'
  2145. X/*++
  2146. X/* NAME
  2147. X/*    dosunix 5
  2148. X/* SUMMARY
  2149. X/*    UNIX <-> MS-DOS text format conversion
  2150. X/* PROJECT
  2151. X/*    pc-mail
  2152. X/* PACKAGE
  2153. X/*    nfs
  2154. X/* SYNOPSIS
  2155. X/*    #include <stdio.h>
  2156. X/*    #include "dosunix.h"
  2157. X/* DESCRIPTION
  2158. X/* .nf
  2159. X
  2160. X /* Anticipate ANSI-compatible compilers */
  2161. X
  2162. X#ifdef __STDC__
  2163. Xint     unix2dos(FILE * ifp, FILE * ofp);
  2164. Xint     dos2unix(FILE * dfp, FILE * pfp);
  2165. Xchar   *dosgets(char *buf, int len, FILE * fp);
  2166. X
  2167. X#else
  2168. Xint     unix2dos();
  2169. Xint     dos2unix();
  2170. Xchar   *dosgets();
  2171. X
  2172. X#endif
  2173. X/* AUTHOR(S)
  2174. X/*    Wietse Z. Venema
  2175. X/*    Eindhoven University of Technology
  2176. X/*    Department of Mathematics and Computer Science
  2177. X/*    Den Dolech 2, P.O. Box 513, 5600 MB Eindhoven, The Netherlands
  2178. X/* CREATION DATE
  2179. X/*    Sun Oct 29 16:41:50 MET 1989
  2180. X/* LAST MODIFICATION
  2181. X/*    10/29/89 22:30:05
  2182. X/* VERSION/RELEASE
  2183. X/*    1.1
  2184. X/*--*/
  2185. X
  2186. END_OF_FILE
  2187. if test 779 -ne `wc -c <'dosunix.h'`; then
  2188.     echo shar: \"'dosunix.h'\" unpacked with wrong size!
  2189. fi
  2190. # end of 'dosunix.h'
  2191. fi
  2192. if test -f 'percentm.h' -a "${1}" != "-c" ; then 
  2193.   echo shar: Will not clobber existing file \"'percentm.h'\"
  2194. else
  2195. echo shar: Extracting \"'percentm.h'\" \(562 characters\)
  2196. sed "s/^X//" >'percentm.h' <<'END_OF_FILE'
  2197. X/*++
  2198. X/* NAME
  2199. X/*    percentm 5
  2200. X/* SUMMARY
  2201. X/*    convert %m to system error message
  2202. X/* PROJECT
  2203. X/*    pc-mail
  2204. X/* PACKAGE
  2205. X/*    nfs
  2206. X/* SYNOPSIS
  2207. X/*    #include percentm.h
  2208. X/* DESCRIPTION
  2209. X/* .nf
  2210. X
  2211. X /* external interface of the percentm module */
  2212. X
  2213. Xextern char *percentm();
  2214. X
  2215. X/* AUTHOR(S)
  2216. X/*    Wietse Z. Venema
  2217. X/*    Eindhoven University of Technology
  2218. X/*    Department of Mathematics and Computer Science
  2219. X/*    Den Dolech 2, P.O. Box 513, 5600 MB Eindhoven, The Netherlands
  2220. X/* CREATION DATE
  2221. X/*    Sun Oct 29 15:29:37 MET 1989
  2222. X/* LAST MODIFICATION
  2223. X/*    10/29/89 22:31:53
  2224. X/* VERSION/RELEASE
  2225. X/*    1.1
  2226. X/*--*/
  2227. X
  2228. END_OF_FILE
  2229. if test 562 -ne `wc -c <'percentm.h'`; then
  2230.     echo shar: \"'percentm.h'\" unpacked with wrong size!
  2231. fi
  2232. # end of 'percentm.h'
  2233. fi
  2234. if test -f 'percentm.c' -a "${1}" != "-c" ; then 
  2235.   echo shar: Will not clobber existing file \"'percentm.c'\"
  2236. else
  2237. echo shar: Extracting \"'percentm.c'\" \(1694 characters\)
  2238. sed "s/^X//" >'percentm.c' <<'END_OF_FILE'
  2239. X/*++
  2240. X/* NAME
  2241. X/*    percentm 3
  2242. X/* SUMMARY
  2243. X/*    convert %m to system error message
  2244. X/* PROJECT
  2245. X/*    pc-mail
  2246. X/* PACKAGE
  2247. X/*    nfs
  2248. X/* SYNOPSIS
  2249. X/*    #include percentm.h
  2250. X/*
  2251. X/*    char *percentm(string, err)
  2252. X/*    char *string;
  2253. X/*    int err;
  2254. X/* DESCRIPTION
  2255. X/*    percentm() interprets %m format specificiers in \fIstring\fR
  2256. X/*    In the output, %m will be replaced by the error message that
  2257. X/*    corresponds with the error value \fIerr\fR (see <errno.h>.
  2258. X/* BUGS
  2259. X/*    The result is stored in static memory that is overwritten with
  2260. X/*    each call.
  2261. X/* AUTHOR(S)
  2262. X/*    Wietse Z. Venema
  2263. X/*    Eindhoven University of Technology
  2264. X/*    Department of Mathematics and Computer Science
  2265. X/*    Den Dolech 2, P.O. Box 513, 5600 MB Eindhoven, The Netherlands
  2266. X/* CREATION DATE
  2267. X/*    Sun Oct 29 15:29:37 MET 1989
  2268. X/* LAST MODIFICATION
  2269. X/*    10/29/89 22:30:06
  2270. X/* VERSION/RELEASE
  2271. X/*    1.1
  2272. X/*--*/
  2273. X
  2274. X#ifndef lint
  2275. Xstatic char sccsid[] = "@(#) percentm.c 1.1 10/29/89 22:30:06";
  2276. X
  2277. X#endif
  2278. X
  2279. X#include <stdio.h>
  2280. X#include "percentm.h"
  2281. X
  2282. Xextern int errno;
  2283. Xextern char *sys_errlist[];
  2284. Xextern int sys_nerr;
  2285. Xextern char *strcpy();
  2286. X
  2287. X/* percentm - replace %m by error message associated with value in err */
  2288. X
  2289. Xchar   *percentm(str, err)
  2290. Xchar   *str;
  2291. Xint     err;
  2292. X{
  2293. X    static char buf[BUFSIZ];
  2294. X    register char *ip = str;
  2295. X    register char *op = buf;
  2296. X
  2297. X    while (*ip) {
  2298. X    switch (*ip) {
  2299. X    case '%':
  2300. X        switch (ip[1]) {
  2301. X        case '\0':                /* don't fall off end */
  2302. X        *op++ = *ip++;
  2303. X        break;
  2304. X        case 'm':                /* replace %m */
  2305. X        (void) strcpy(op,
  2306. X            sys_errlist[(err < sys_nerr && err > 0) ? err : 0]);
  2307. X        op += strlen(op);
  2308. X        ip += 2;
  2309. X        break;
  2310. X        default:                /* leave %<any> alone */
  2311. X        *op++ = *ip++, *op++ = *ip++;
  2312. X        break;
  2313. X        }
  2314. X    default:
  2315. X        *op++ = *ip++;
  2316. X    }
  2317. X    }
  2318. X    return (buf);
  2319. X}
  2320. X
  2321. END_OF_FILE
  2322. if test 1694 -ne `wc -c <'percentm.c'`; then
  2323.     echo shar: \"'percentm.c'\" unpacked with wrong size!
  2324. fi
  2325. # end of 'percentm.c'
  2326. fi
  2327. if test -f 'pc-mail.8' -a "${1}" != "-c" ; then 
  2328.   echo shar: Will not clobber existing file \"'pc-mail.8'\"
  2329. else
  2330. echo shar: Extracting \"'pc-mail.8'\" \(1779 characters\)
  2331. sed "s/^X//" >'pc-mail.8' <<'END_OF_FILE'
  2332. X.TH PC-MAIL 8 
  2333. X.ad
  2334. X.fi
  2335. X.SH NAME
  2336. Xpc-mail
  2337. X\-
  2338. Xdeliver mail to nfs-based pc-mail users
  2339. X.SH PROJECT
  2340. X.na
  2341. X.nf
  2342. Xpc-mail
  2343. X.SH PACKAGE
  2344. X.na
  2345. X.nf
  2346. Xnfs
  2347. X.SH SYNOPSIS
  2348. X.na
  2349. X.nf
  2350. Xpc-mail user
  2351. X.SH DESCRIPTION
  2352. X.ad
  2353. X.fi
  2354. XThis program is to be run on the nfs server that exports mail
  2355. Xdirectories to MS-DOS pc-mail users. The program replaces the
  2356. XUNIX -> MS-DOS file transfer function of the MS-DOS \fIcico\fR
  2357. Xprogram.
  2358. X
  2359. XNormally, the pc-mail delivery program is invoked by sendmail(8).
  2360. XIts purpose is to deliver new mail in the mail directory of the
  2361. Xspecified \fIuser\fR (default /var/spool/pc-mail/\fIuser\fR).
  2362. XAny error conditions detected by the pc-mail delivery program
  2363. Xare reported back in a sendmail-compatible manner.
  2364. X
  2365. XThis program must be run with root privileges. It will assume
  2366. Xthe (uid, gid) of the specified user before delivering mail.
  2367. X
  2368. XThe program attempts to create any missing directories, and to
  2369. Xcorrect ownerships or protections where needed.
  2370. X.SH FILES
  2371. X.na
  2372. X.nf
  2373. X/usr/spool/pc-mail/\fIuser\fR/nNNNNN, mail message.
  2374. X/usr/spool/pc-mail/\fIuser\fR/hNNNNN, sender of message.
  2375. X(NNNNN is the pc-mail "message id").
  2376. X.SH SEE ALSO
  2377. X.na
  2378. X.nf
  2379. Xpc-maild(1)
  2380. X.SH DIAGNOSTICS
  2381. X.ad
  2382. X.fi
  2383. XAll conceivable error conditions cause the program to terminate
  2384. Xwith a non-zero exit status, after printing an error message on
  2385. Xthe standard error stream, and appending an entry to the system log.
  2386. XSee <sysexits.h> for details.
  2387. X.SH BUGS
  2388. X.ad
  2389. X.fi
  2390. XThere is no way to notify a pc-mail user of the arrival of new mail.
  2391. X.SH AUTHOR(S)
  2392. X.na
  2393. X.nf
  2394. XW.Z. Venema
  2395. XEindhoven University of Technology
  2396. XDepartment of Mathematics and Computer Science
  2397. XDen Dolech 2, P.O. Box 513, 5600 MB Eindhoven, The Netherlands
  2398. X.SH CREATION DATE
  2399. X.na
  2400. X.nf
  2401. XSun Oct 22 18:00:53 MED 1989
  2402. X.SH LAST MODIFICATION
  2403. X.na
  2404. X.nf
  2405. X11/19/89 13:46:04
  2406. X.SH VERSION/RELEASE
  2407. X.na
  2408. X.nf
  2409. X1.2
  2410. END_OF_FILE
  2411. if test 1779 -ne `wc -c <'pc-mail.8'`; then
  2412.     echo shar: \"'pc-mail.8'\" unpacked with wrong size!
  2413. fi
  2414. # end of 'pc-mail.8'
  2415. fi
  2416. if test -f 'pc-maild.8' -a "${1}" != "-c" ; then 
  2417.   echo shar: Will not clobber existing file \"'pc-maild.8'\"
  2418. else
  2419. echo shar: Extracting \"'pc-maild.8'\" \(1766 characters\)
  2420. sed "s/^X//" >'pc-maild.8' <<'END_OF_FILE'
  2421. X.TH PC-MAILD 8 
  2422. X.ad
  2423. X.fi
  2424. X.SH NAME
  2425. Xpc-maild
  2426. X\-
  2427. Xdeliver unsent mail
  2428. X.SH PROJECT
  2429. X.na
  2430. X.nf
  2431. Xpc-mail
  2432. X.SH PACKAGE
  2433. X.na
  2434. X.nf
  2435. Xnfs
  2436. X.SH SYNOPSIS
  2437. X.na
  2438. X.nf
  2439. Xpc-maild [delay]
  2440. X.SH DESCRIPTION
  2441. X.ad
  2442. X.fi
  2443. XThis program should be run on the nfs file server that exports
  2444. Xmail directories to MS-DOS pc-mail users. It replaces the
  2445. X(MS-DOS -> UNIX) transmission function of the MS-DOS \fIcico\fR
  2446. Xprogram.
  2447. X
  2448. XThe per-user mail directories (default: /var/spool/pc-mail/\fIuser\fR)
  2449. Xare scanned for outgoing mail every \fIdelay\fR seconds (default: 300).
  2450. XWhen outgoing mail is found, it is sent through the UNIX rmail program
  2451. X(uucp mail interface) and the corresponding files are removed from the
  2452. Xuser\'s mail directory.
  2453. X
  2454. XThe program should run with root privileges. It will assume
  2455. Xthe (uid, gid) of the sending user before accessing mail files.
  2456. X.SH COMMANDS
  2457. X.na
  2458. X.nf
  2459. Xrmail(1), uucp mail interface program
  2460. X.SH FILES
  2461. X.na
  2462. X.nf
  2463. X/usr/spool/pc-mail/\fIuser\fR/dNNNNN, mail message
  2464. X/usr/spool/pc-mail/\fIuser\fR/xNNNNN, recipients
  2465. X(NNNNN is the pc-mail "message id").
  2466. X.SH SEE ALSO
  2467. X.na
  2468. X.nf
  2469. Xpc-mail(1)
  2470. X.SH DIAGNOSTICS
  2471. X.ad
  2472. X.fi
  2473. XErrors found during initialization cause the program to
  2474. Xterminate with a diagnostic on the standard error stream.
  2475. XAll other errors are considered transient, i.e. if something
  2476. Xfails, it is tried again at a later time.  Where possible,
  2477. Xdiagnostics are logged through the syslog facility.
  2478. X.SH BUGS
  2479. X.ad
  2480. X.fi
  2481. XScanning mail directories is an inefficient way to detect
  2482. Xunsent mail.
  2483. X.SH AUTHOR(S)
  2484. X.na
  2485. X.nf
  2486. XW.Z. Venema
  2487. XEindhoven University of Technology
  2488. XDepartment of Mathematics and Computer Science
  2489. XDen Dolech 2, P.O. Box 513, 5600 MB Eindhoven, The Netherlands
  2490. X.SH CREATION DATE
  2491. X.na
  2492. X.nf
  2493. XSun Oct 22 22:12:15 MED 1989
  2494. X.SH LAST MODIFICATION
  2495. X.na
  2496. X.nf
  2497. X10/31/89 15:44:54
  2498. X.SH VERSION/RELEASE
  2499. X.na
  2500. X.nf
  2501. X1.3
  2502. END_OF_FILE
  2503. if test 1766 -ne `wc -c <'pc-maild.8'`; then
  2504.     echo shar: \"'pc-maild.8'\" unpacked with wrong size!
  2505. fi
  2506. # end of 'pc-maild.8'
  2507. fi
  2508. echo shar: End of shell archive.
  2509. exit 0
  2510.  
  2511.